# Para visualización en notebook
import matplotlib.pyplot as plt
import matplotlib as mpl
import seaborn as sns
# Parámetros de visualización
sns.set_context('talk')
mpl.rcParams['figure.figsize'] = (8, 6)
import os
from collections import Counter
# Números y Datos
import numpy as np
import pandas as pd
import networkx as nx
from networkx.algorithms.approximation import average_clustering
from glob import glob
from pathlib import Path
import urllib.request
url = "https://www.dropbox.com/scl/fi/nk8yvhez5ylhd6blzf77o/airport.txt?rlkey=3cf24r6yij8uu0fakb68yztlm&dl=1"
urllib.request.urlretrieve(url, "airport.txt")
print("Descarga completa: airport.txt")
url = "https://www.dropbox.com/scl/fi/t62q9swnah7nvu34falkj/celegans.txt?rlkey=lxg2kashijntfi0bwmeuty5ja&dl=1"
urllib.request.urlretrieve(url, "celegans.txt")
print("Descarga completa: celegans.txt")
url = "https://www.dropbox.com/scl/fi/eebzjgqazi8b02bkkrxmf/airStrongly_positions.pkl?rlkey=cyhifzsgrls5vdlycrb1gnykv&st=6lozmqe6&dl=1"
urllib.request.urlretrieve(url, "airportStronglyConn_pos.pkl")
print("Descarga completa: airportStronglyConn_pos.pkl")
Descarga completa: airport.txt Descarga completa: celegans.txt Descarga completa: airportStronglyConn_pos.pkl
# DATOS REDES:
#!wget -O airport.txt https://www.dropbox.com/scl/fi/nk8yvhez5ylhd6blzf77o/airport.txt?rlkey=3cf24r6yij8uu0fakb68yztlm&dl=1
#!wget -O facebook.txt https://www.dropbox.com/scl/fi/hdgcmyss47w9t676kh2ug/facebook.txt?rlkey=j616y86ejfn6f719jg4b8e413&dl=1
#!wget -O lesmiserables.txt https://www.dropbox.com/scl/fi/ex7183k4zjgxbiw0diwi3/lesmiserables.txt?rlkey=zx5u5371s7gw3jlv50363jycf&dl=1
#!wget -O terrorist.txt https://www.dropbox.com/scl/fi/2vl6hcazv5v13r7scodod/terrorist.txt?rlkey=l0n1rxbby6a8irtlyh1tbbweo&dl=1
#!wget -O celegans.txt https://www.dropbox.com/scl/fi/t62q9swnah7nvu34falkj/celegans.txt?rlkey=lxg2kashijntfi0bwmeuty5ja&dl=1
#!wget -O email.txt https://www.dropbox.com/scl/fi/w5o34b0olg7xek4s42lml/email-Eu-core.txt?rlkey=g2561imdd4ssyrwfgywrotzwm&st=czqgmef0&dl=1
#!wget -O email_labels.txt https://www.dropbox.com/scl/fi/ij3b6jul7ispiovt18sfm/email-Eu-core-department-labels.txt?rlkey=dqp60qw20pw7biil9cvti4u68&st=zij9wsi8&dl=1
# AHORA ARCHIVOS DE POSICION DE LOS NODOS:
#!wget -O airportStronglyConn_pos.pkl https://www.dropbox.com/scl/fi/eebzjgqazi8b02bkkrxmf/airStrongly_positions.pkl?rlkey=cyhifzsgrls5vdlycrb1gnykv&st=6lozmqe6&dl=1
#!wget -O email_pos.pkl https://www.dropbox.com/scl/fi/loeuul6gxq7uscd1m7ks8/email_positions.pkl?rlkey=caf194s8198pffo2zaq6767jz&st=kw0c3tu4&dl=1
#!wget -O fb_pos.pkl https://www.dropbox.com/scl/fi/ka6v0h9ew5j08haxlbf6b/fb_positions.pkl?rlkey=7ul7jr7re5bziy54cgp3x9tre&st=vp6gjciw&dl=1
'wget' is not recognized as an internal or external command, operable program or batch file. 'dl' is not recognized as an internal or external command, operable program or batch file. 'wget' is not recognized as an internal or external command, operable program or batch file. 'dl' is not recognized as an internal or external command, operable program or batch file. 'wget' is not recognized as an internal or external command, operable program or batch file. 'st' is not recognized as an internal or external command, operable program or batch file. 'dl' is not recognized as an internal or external command, operable program or batch file.
def read_graph(filename):
G = nx.Graph()
array = np.loadtxt(filename, dtype=int)
G.add_edges_from(array)
return G
def read_graph_weighted(filename):
G = nx.Graph()
array = np.loadtxt(filename, dtype=int)
G.add_weighted_edges_from(array)
return G
def read_dir_graph(filename):
G = nx.DiGraph()
array = np.loadtxt(filename, dtype=int)
G.add_edges_from(array)
return G
def read_dir_graph_weighted(filename):
G = nx.DiGraph()
array = np.loadtxt(filename, dtype=int)
G.add_weighted_edges_from(array)
return G
celegans= read_graph_weighted('celegans.txt')
print('C. elegans')
print(celegans)
print('Es dirigido?:',nx.is_directed(celegans))
print('Es pesado?:',nx.is_weighted(celegans))
print('Es conectado?:',nx.is_connected(celegans))
print('')
air = read_dir_graph_weighted('airport.txt')
print('Airport')
print(air)
print('Es dirigido?:',nx.is_directed(air))
print('Es pesado?:',nx.is_weighted(air))
print('Es fuertemente conexo?:',nx.is_strongly_connected(air))
print('Es debilmente conexo?:',nx.is_weakly_connected(air))
C. elegans Graph with 297 nodes and 2148 edges Es dirigido?: False Es pesado?: True Es conectado?: True Airport DiGraph with 1574 nodes and 28236 edges Es dirigido?: True Es pesado?: True Es fuertemente conexo?: False Es debilmente conexo?: False
# Definición de Funciones
'''
Permite obtener una Matriz de Adyacencia Pesada (MAP)
a partir de los datos contenidos en el archivo especificado
Substrae una matriz diagonal de 1s para evitar conexiones
reflexivas (un nodo consigo mismo)
'''
def obtener_map(nombre_archivo):
df = pd.read_csv(nombre_archivo, header=None)
matAdyacPesada = df.values
n = matAdyacPesada.shape[0]
matAdyacPesada -= np.diag(np.ones(n))
return matAdyacPesada
'''
Crea un heatmap a partir de una matriz
'''
def graficar_heatmap(matriz, titulo=''):
sns.heatmap(matriz)
n = matriz.shape[0]
plt.xlim(0, n)
plt.ylim(0, n)
plt.title(titulo)
plt.show()
'''
Exporta un archivo de imagen
de un heatmap obtenido a partir de una matriz
'''
def exportar_heatmap(matriz, nombre_archivo='imagen_01.png'):
sns.heatmap(matriz)
n = matriz.shape[0]
plt.xlim(0, n)
plt.ylim(0, n)
plt.savefig(nombre_archivo, dpi=300, bbox_inches='tight')
plt.close()
'''
Data una matriz de adyacencia pesada y un valor
de densidad de enlaces, calcula el valor umbral
necesario para representar valores que estén
por encima de la densidad de enlaces dada
'''
def densidad_a_umbral(matriz, densidad=0.1):
n = matriz.shape[0]
tril_idx = np.tril_indices(n, -1)
c = sorted(np.array(list(matriz[tril_idx].reshape(-1))), reverse=True)
return c[int((len(c)-1)*densidad)]
'''
Permite representar un grafo
'''
def representar_grafo(G, titulo='', zip_de_layout=None, mostrar_etiquetas=True, nombre_archivo=None):
plt.figure(figsize=(8, 6))
plt.title(titulo, fontsize=14)
nx.draw(G, zip_de_layout, with_labels=mostrar_etiquetas, node_size=25, width=0.1, linewidths=0.25)
if not nombre_archivo == None:
plt.savefig(nombre_archivo, dpi=300, bbox_inches='tight')
plt.show()
'''
Permite representar un grafo a partir de una matriz
de Adyacencia - Agrega una escala de colores para los
nodos, que refleja el grado
Paletas disponibles: plt.cm.{Grays|Blues|BuGn|PuRd|Oranges}
'''
def representar_grafo_escala_colores(G, escala_color='grados', titulo='', zip_de_layout=None, mostrar_etiquetas=False, nombre_archivo=None):
if escala_color == 'grados':
valores_escala = dict(G.degree())
elif escala_color == 'clustering':
valores_escala = nx.clustering(G)
nodos = G.nodes()
n = len(list(nodos))
n_color = np.asarray([valores_escala[n] for n in nodos])
vmin = min(n_color)
vmax = max(n_color)
cmap = plt.cm.Oranges
norm = plt.Normalize(vmin = vmin, vmax=vmax)
plt.figure(figsize=(9,6))
plt.title(titulo, fontsize=14)
nx.draw(G, zip_de_layout, node_size=25, node_color=n_color, width=0.1, linewidths=0.25, vmin=vmin, vmax=vmax,cmap=cmap)
sm = plt.cm.ScalarMappable(cmap=cmap, norm=norm)
plt.colorbar(sm, ax=plt.gca())
if not nombre_archivo==None:
plt.savefig(nombre_archivo, dpi=300, bbox_inches='tight')
plt.show()
'''
En Grafos dirigidos, permite obtener la mayor componente altamente conexa
'''
def obtener_mayor_componente_fuertemente_conexa(G):
if nx.is_directed(G):
StronglyCC = sorted(nx.strongly_connected_components(G), key=len, reverse=True)
return G.subgraph(StronglyCC[0])
else:
return None
'''
Calcula el diámetro del Grafo teniendo en cuenta:
Si la red es no dirigida:
Si la red es conexa, devuelve el diametro directo
Si no es conexa devuelve el diámetro de la componente gigante
Si la red es dirigida:
Si está fuertemente conectada devuelve el diametro
Si no está fuertemente conectada, devuelve el diámetro de la mayor componente fuertemente conectada
'''
def calcular_diametro(G):
if not nx.is_directed(G):
if nx.is_connected(G):
print("La red no dirigida y conexa, obteniendo diámetro en forma directa")
D = nx.diameter(G)
else:
print("La red es no dirigida y no es conexa. Retornando el diámetro de la componente gigante.")
gigante = G.subgraph(max(nx.connected_components(G), key=len)).copy()
D = nx.diameter(gigante)
else:
if nx.is_strongly_connected(G):
print("La red es dirigida y fuertemente conexa, obteniendo diámetro en forma directa")
D = nx.diameter(G)
else:
largest_scc = max(nx.strongly_connected_components(G), key=len)
G_scc = G.subgraph(largest_scc).copy()
print("La red es dirigida y no fuertemente conexa, obteniendo diámetro de la mayor componente fuertemente conexa")
D = nx.diameter(G_scc)
return D
'''
Para redes muy grandes, calcula la distancia media por sampleo
tomando n pares de nodos, calculando entre ellos la distancia más
corta y luego promediando.
Utilizo el decorator @retry porque en ciertos ejemplos, uno o más pares de nodos
elegidos pueden no estar conectados y luego su camino no está definido, arrojando
una excepción. Retry me permite avanzar desestimando el error
'''
def calcular_distancia_media_y_eff_por_sampleo(G, numero_muestras=100):
nodos = list(G)
if numero_muestras > len(nodos):
numero_muestras = len(nodos)
if numero_muestras > 100000:
numero_muestras = 100000
pares = np.random.choice(nodos, (numero_muestras, 2))
distancias = [nx.shortest_path_length(G, *par)
for par in pares]
inversas = [(1/nx.shortest_path_length(G, *par))
for par in pares]
return np.mean(distancias), np.mean(inversas)
'''
Devuelve el grado promedio y el nodo con mayor grado
'''
def calcular_grados(matriz, densidad=0.1):
G = nx.from_numpy_array(matriz)
if nx.is_weighted(G):
umbral = densidad_a_umbral(matriz, densidad)
G = nx.from_numpy_array(matriz >= umbral)
else:
G = nx.from_numpy_array(matriz)
grados = [G.degree(n) for n in G.nodes()]
promedio = np.mean(grados)
nodo_max = max(G.degree(), key=lambda x: x[1])
return promedio, nodo_max
'''
Analiza y reporta varios parametros de los grafos
'''
def analizar_grafo(G):
print('Es un grafo dirigido?:',nx.is_directed(G))
print('Es un grafo pesado?:',nx.is_weighted(G))
if not nx.is_directed(G):
print('Es un grafo conectado?:',nx.is_connected(G))
else:
print('Grafo dirigido no acepta definición de conexo')
diametro = calcular_diametro(G)
print(f"Diámetro: {diametro}")
if nx.is_directed(G):
print('Es un grafo fuertemente conexo?:',nx.is_strongly_connected(G))
print('Es un grafo debilmente conexo?:',nx.is_weakly_connected(G))
componente_mayor_fuertemente_conexa = obtener_mayor_componente_fuertemente_conexa(G)
print("Componente mayor fuertemente conexa")
print(componente_mayor_fuertemente_conexa)
else:
print("Por no ser dirigido no acepta determinación de fuertemente o débilmente conexo")
# Por si es dirigido tenemos que hacer esto
# Cálculo de distancia media
if nx.is_directed(G):
H = G.to_undirected()
print("El grafo no es conexo, calculando la distancia media y la eficiencia de la componente gigante")
print("Esta es una lista de las componentes conexas y su distancia media")
for componente_nodos in nx.connected_components(H):
subgrafo = H.subgraph(componente_nodos)
n = subgrafo.number_of_nodes()
if nx.is_connected(subgrafo) and n > 1:
L = nx.average_shortest_path_length(subgrafo)
print(f"- Componente de {n} nodos con distancia media: {L:.3f}")
#elif n == 1:
# print(f"- Componente aislada de 1 nodo (sin distancia definida)")
gigante = H.subgraph(max(nx.connected_components(H), key=len)).copy()
distancia_media_directa = nx.average_shortest_path_length(gigante)
nodos_gigante = gigante.number_of_nodes()
print(f"La componente Gigante tiene {nodos_gigante} nodos")
eficiencia_directa = nx.global_efficiency(gigante)
distancia_media_sampleo, eficiencia_sampleo = calcular_distancia_media_y_eff_por_sampleo(gigante)
print(f"Distancia Media de la Componente Gigante obtenida por muestreo: {distancia_media_sampleo}")
print(f"Distancia Media Directa de la Componente Gigante: {distancia_media_directa}")
print(f"Eficiencia Global de la Componente Gigante obtenida por muestreo: {eficiencia_sampleo}")
print(f"Eficiencia Global Directa de la Componente Gigante: {eficiencia_directa}")
eficiencia_directa = nx.global_efficiency(H)
print(f"Eficiencia Global Directa del Grafo: {eficiencia_directa}")
elif nx.is_connected(G):
distancia_media_directa = nx.average_shortest_path_length(G)
distancia_media_sampleo, eficiencia_sampleo = calcular_distancia_media_y_eff_por_sampleo(G)
print(f"Distancia Media del Grafo obtenida por muestreo: {distancia_media_sampleo}")
print(f"Distancia Media Diecta del Grafo: {distancia_media_directa}")
print(f"Eficiencia Global Del Grafo obtenida por muestreo: {eficiencia_sampleo}")
eficiencia_directa = nx.global_efficiency(G)
print(f"Eficiencia Global Directa del Grafo: {eficiencia_directa}")
else:
print("El grafo no es conexo, calculando la distancia media y la eficiencia de la componente gigante")
print("Esta es una lista de las componentes conexas y su distancia media")
for componente_nodos in nx.connected_components(G):
subgrafo = G.subgraph(componente_nodos)
n = subgrafo.number_of_nodes()
if nx.is_connected(subgrafo) and n > 1:
L = nx.average_shortest_path_length(subgrafo)
print(f"- Componente de {n} nodos con distancia media: {L:.3f}")
#elif n == 1:
# print(f"- Componente aislada de 1 nodo (sin distancia definida)")
gigante = G.subgraph(max(nx.connected_components(G), key=len)).copy()
distancia_media_directa = nx.average_shortest_path_length(gigante)
nodos_gigante = gigante.number_of_nodes()
print(f"La componente Gigante tiene {nodos_gigante} nodos")
eficiencia_directa = nx.global_efficiency(gigante)
distancia_media_sampleo, eficiencia_sampleo = calcular_distancia_media_y_eff_por_sampleo(gigante)
print(f"Distancia Media de la Componente Gigante obtenida por muestreo: {distancia_media_sampleo}")
print(f"Distancia Media Directa de la Componente Gigante: {distancia_media_directa}")
print(f"Eficiencia Global de la Componente Gigante obtenida por muestreo: {eficiencia_sampleo}")
print(f"Eficiencia Global Directa de la Componente Gigante: {eficiencia_directa}")
eficiencia_directa = nx.global_efficiency(G)
print(f"Eficiencia Global Directa del Grafo: {eficiencia_directa}")
def graficar_distribucion_grados(G, bins=10, titulo='Distribución de Grados', nombre_archivo=None):
plt.figure(figsize=(6, 4))
grados = [G.degree(n) for n in G.nodes()]
hist, bins, _ = plt.hist(grados, bins=bins, density=True)
plt.xlabel('k')
plt.ylabel('p(k)')
plt.title(titulo)
if not nombre_archivo == None:
plt.savefig(nombre_archivo, dpi=300, bbox_inches='tight')
plt.show()
def graficar_distribucion_grados_normalizada(G, bins=10, titulo='Distribución de Grado Normalizada', nombre_archivo=None):
grados = [G.degree(n) for n in G.nodes()]
conteo = Counter(grados)
total_nodos = G.number_of_nodes()
# Crear distribución normalizada
grados_k = sorted(conteo.keys())
pk = [conteo[k] / total_nodos for k in grados_k]
# Graficar
plt.figure(figsize=(6, 4))
plt.bar(grados_k, pk, width=0.8, color='skyblue', edgecolor='black')
#plt.hist(grados_k, bins=bins, density=True)
plt.xlabel('Grado k')
plt.ylabel('p(k)')
plt.title(titulo)
if nombre_archivo:
plt.savefig(nombre_archivo, dpi=300, bbox_inches='tight')
plt.show()
def read_graph(filename):
G = nx.Graph()
array = np.loadtxt(filename, dtype=int)
G.add_edges_from(array)
return G
def read_graph_weighted(filename):
G = nx.Graph()
array = np.loadtxt(filename, dtype=int)
G.add_weighted_edges_from(array)
return G
def read_dir_graph(filename):
G = nx.DiGraph()
array = np.loadtxt(filename, dtype=int)
G.add_edges_from(array)
return G
def read_dir_graph_weighted(filename):
G = nx.DiGraph()
array = np.loadtxt(filename, dtype=int)
G.add_weighted_edges_from(array)
return G
print("=== C. elegans ===")
G_ce = read_graph_weighted('celegans.txt')
print(G_ce)
analizar_grafo(G_ce)
=== C. elegans === Graph with 297 nodes and 2148 edges Es un grafo dirigido?: False Es un grafo pesado?: True Es un grafo conectado?: True La red no dirigida y conexa, obteniendo diámetro en forma directa Diámetro: 5 Por no ser dirigido no acepta determinación de fuertemente o débilmente conexo Distancia Media del Grafo obtenida por muestreo: 2.52 Distancia Media Diecta del Grafo: 2.455318955318955 Eficiencia Global Del Grafo obtenida por muestreo: 0.4341666666666668 Eficiencia Global Directa del Grafo: 0.4448228531562069
# Matriz de adyacencia pesada (reemplaza con tu archivo real si difiere)
mat_ce = nx.to_numpy_array(G_ce, weight='weight')
np.fill_diagonal(mat_ce, 0)
# Heatmap
mat_ce = nx.to_numpy_array(G_ce, weight='weight')
np.fill_diagonal(mat_ce, 0)
# Heatmap y export
graficar_heatmap(mat_ce, titulo='Heatmap C. elegans')
exportar_heatmap(mat_ce, nombre_archivo='heatmap_celegans.png')
# Umbral (10%)
umbral_ce = densidad_a_umbral(mat_ce, densidad=0.1)
print(f'Umbral C. elegans (10% densidad): {umbral_ce}')
# Layout y representación del grafo
pos_ce = nx.spring_layout(G_ce, seed=42)
representar_grafo(G_ce, titulo='C. elegans (estructura)', zip_de_layout=pos_ce)
representar_grafo_escala_colores(
G_ce,
escala_color='grados',
titulo='C. elegans (grado de nodo)',
zip_de_layout=pos_ce
)
# Distribución de grados
graficar_distribucion_grados(G_ce, bins=20, titulo='Distribución de grados (C. elegans)')
graficar_distribucion_grados_normalizada(
G_ce, bins=20, titulo='Distribución normalizada de grados (C. elegans)'
)
Umbral C. elegans (10% densidad): 0.0
# -------------------------------------------------
# Análisis para Airport
# -------------------------------------------------
print("\n=== Airport ===")
G_air = read_dir_graph_weighted('airport.txt')
print(G_air)
analizar_grafo(G_air)
=== Airport === DiGraph with 1574 nodes and 28236 edges Es un grafo dirigido?: True Es un grafo pesado?: True Grafo dirigido no acepta definición de conexo La red es dirigida y no fuertemente conexa, obteniendo diámetro de la mayor componente fuertemente conexa Diámetro: 9 Es un grafo fuertemente conexo?: False Es un grafo debilmente conexo?: False Componente mayor fuertemente conexa DiGraph with 1402 nodes and 28032 edges El grafo no es conexo, calculando la distancia media y la eficiencia de la componente gigante Esta es una lista de las componentes conexas y su distancia media - Componente de 1572 nodos con distancia media: 3.115 - Componente de 2 nodos con distancia media: 1.000 La componente Gigante tiene 1572 nodos
--------------------------------------------------------------------------- ZeroDivisionError Traceback (most recent call last) Cell In[13], line 7 5 G_air = read_dir_graph_weighted('airport.txt') 6 print(G_air) ----> 7 analizar_grafo(G_air) Cell In[10], line 213, in analizar_grafo(G) 211 print(f"La componente Gigante tiene {nodos_gigante} nodos") 212 eficiencia_directa = nx.global_efficiency(gigante) --> 213 distancia_media_sampleo, eficiencia_sampleo = calcular_distancia_media_y_eff_por_sampleo(gigante) 214 print(f"Distancia Media de la Componente Gigante obtenida por muestreo: {distancia_media_sampleo}") 215 print(f"Distancia Media Directa de la Componente Gigante: {distancia_media_directa}") Cell In[10], line 148, in calcular_distancia_media_y_eff_por_sampleo(G, numero_muestras) 145 pares = np.random.choice(nodos, (numero_muestras, 2)) 146 distancias = [nx.shortest_path_length(G, *par) 147 for par in pares] --> 148 inversas = [(1/nx.shortest_path_length(G, *par)) 149 for par in pares] 150 return np.mean(distancias), np.mean(inversas) Cell In[10], line 148, in <listcomp>(.0) 145 pares = np.random.choice(nodos, (numero_muestras, 2)) 146 distancias = [nx.shortest_path_length(G, *par) 147 for par in pares] --> 148 inversas = [(1/nx.shortest_path_length(G, *par)) 149 for par in pares] 150 return np.mean(distancias), np.mean(inversas) ZeroDivisionError: division by zero
# Matriz de adyacencia pesada (reemplaza con tu archivo real si difiere)
#mat_air = obtener_map(G_air)
import networkx as nx
import numpy as np
import pandas as pd
# convierte G_air en un DataFrame N×N con los pesos
df_adj = nx.to_pandas_adjacency(G_air, dtype=float, weight='weight')
# fuerza ceros en la diagonal (quita self‐loops)
np.fill_diagonal(df_adj.values, 0)
# si quieres, guardas en CSV para reusar obtener_map:
df_adj.to_csv('airport_adj.csv', header=False, index=False)
# y ya:
mat_air = df_adj.values
# Heatmap
graficar_heatmap(mat_air, titulo='Heatmap Airport')
#exportar_heatmap(mat_air, nombre_archivo='heatmap_airport.png')
# Umbral para un 10% de densidad
umbral_air = densidad_a_umbral(mat_air, densidad=0.1)
print(f'Umbral (10%): {umbral_air}')
# Layout y representación del grafo
pos_air = nx.spring_layout(G_air, seed=42)
representar_grafo(G_air, titulo='Airport (estructura)', zip_de_layout=pos_air, mostrar_etiquetas=False)
representar_grafo_escala_colores(
G_air,
escala_color='clustering',
titulo='Airport (coeficiente de clustering)',
zip_de_layout=pos_air,
mostrar_etiquetas=False
)
# Distribución de grados
graficar_distribucion_grados(G_air, bins=20, titulo='Distribución de grados (Airport)')
graficar_distribucion_grados_normalizada(
G_air, bins=20, titulo='Distribución normalizada de grados (Airport)'
)
Umbral (10%): 0.0
import pickle
import matplotlib.pyplot as plt
import networkx as nx
# 1) Carga el grafo dirigido y ponderado
G_air = read_dir_graph_weighted('airport.txt')
# 2) Extrae la mayor componente fuertemente conexa (tu propia función)
H = obtener_mayor_componente_fuertemente_conexa(G_air)
# 3) Carga el dict de posiciones desde el .pkl
with open('airportStronglyConn_pos.pkl', 'rb') as f:
pos = pickle.load(f)
# pos debe ser un dict { nodo: (x, y), ... }
# 4) Dibuja:
plt.figure(figsize=(12, 12))
nx.draw_networkx_nodes(H, pos,
node_size=10,
node_color='steelblue',
alpha=0.7)
nx.draw_networkx_edges(H, pos,
edge_color='gray',
width=0.3,
arrowsize=2,
alpha=0.5)
plt.title("Subgrafo fuertemente conexo de Airport")
plt.axis('off')
plt.show()
import numpy as np
import networkx as nx
def plotWeightedGraph(G, pos, colorMapping, magnification, nodeSize=45):
# 1) nodos con color por mapping
values = [ colorMapping.get(n, 0.0) for n in G.nodes() ]
nx.draw_networkx_nodes(G, pos=pos,
node_size=nodeSize,
node_color=values)
# 2) etiquetas (puedes quitar esta línea si sobra)
nx.draw_networkx_labels(G, pos,
labels={n: n for n in G.nodes()},
font_size=7,
font_color='white')
# 3) grosores de arista según peso
# obtenemos la lista de pesos en el mismo orden que G.edges()
weights = [ G[u][v].get('weight', 1.0) for u, v in G.edges() ]
edgeWidths = np.array(weights, dtype=float)
if edgeWidths.max() > 0:
edgeWidths = magnification * (edgeWidths / edgeWidths.max())
# desplazamos mínimo a 0.5 para que se vean todas las aristas
edgeWidths = edgeWidths - edgeWidths.min() + 0.5
else:
edgeWidths = np.full_like(edgeWidths, 0.5)
nx.draw_networkx_edges(G, pos,
edgelist=G.edges(),
width=edgeWidths,
edge_color='gray')
# --- Ejemplo de uso ---
# 1) Carga el grafo completo
G_air = read_dir_graph_weighted('airport.txt')
# 2) Extrae la componente fuertemente conexa
H_air = obtener_mayor_componente_fuertemente_conexa(G_air)
# 3) Carga las posiciones de esa componente
with open('airportStronglyConn_pos.pkl','rb') as f:
pos_air = pickle.load(f)
# 4) Centralidad de H_air, no de G_air
cent_air = nx.degree_centrality(H_air)
# 5) Dibuja solo H_air con pos_air
plotWeightedGraph(H_air, pos_air, cent_air,
magnification=10, nodeSize=60)
# Para C. elegans:
G_ce = read_graph_weighted('celegans.txt')
pos_ce = nx.spring_layout(G_ce, seed=42)
cent_ce = nx.degree_centrality(G_ce)
plotWeightedGraph(G_ce, pos_ce, cent_ce, magnification=10, nodeSize=45)
import networkx as nx
import matplotlib.pyplot as plt
import pickle
def plot_centrality_with_colorbar(G, pos, centrality, title, cmap=plt.cm.plasma):
"""
Dibuja G usando 'pos', coloreando y escalando nodos según 'centrality',
y añade una barra de colores.
"""
# Preparamos valores normalizados y tamaños
vals = list(centrality.values())
norm_vals = [(v - min(vals)) / (max(vals) - min(vals) + 1e-6) for v in vals]
sizes = [100 + 900 * v for v in norm_vals]
fig, ax = plt.subplots(figsize=(6,6))
nodes = nx.draw_networkx_nodes(
G, pos,
node_size=sizes,
node_color=vals,
cmap=cmap,
ax=ax
)
nx.draw_networkx_edges(G, pos, alpha=0.3, ax=ax)
ax.set_title(title)
ax.axis('off')
# Escala de colores
sm = plt.cm.ScalarMappable(
cmap=cmap,
norm=plt.Normalize(vmin=min(vals), vmax=max(vals))
)
sm.set_array([])
cbar = fig.colorbar(sm, ax=ax, fraction=0.046, pad=0.04)
cbar.set_label('Centralidad', rotation=270, labelpad=15)
plt.show()
# --- 1) Grafo dirigido: Airport (componente fuertemente conexa) ---
G_air = read_dir_graph_weighted('airport.txt')
H_air = obtener_mayor_componente_fuertemente_conexa(G_air)
with open('airportStronglyConn_pos.pkl','rb') as f:
pos_air = pickle.load(f)
# Calculamos dos medidas de centralidad
deg_air = nx.degree_centrality(H_air) # grado (in+out)
pr_air = nx.pagerank(H_air, weight='weight')
# Dibujamos cada una con su colorbar
plot_centrality_with_colorbar(H_air, pos_air, deg_air,
"Airport: Degree Centrality")
plot_centrality_with_colorbar(H_air, pos_air, pr_air,
"Airport: PageRank")
# --- 2) Grafo no dirigido: C. elegans ---
G_ce = read_graph_weighted('celegans.txt')
pos_ce = nx.spring_layout(G_ce, iterations=1000, seed=42)
deg_ce = nx.degree_centrality(G_ce)
btw_ce = nx.betweenness_centrality(G_ce, weight='weight', normalized=True)
plot_centrality_with_colorbar(G_ce, pos_ce, deg_ce,
"C. elegans: Degree Centrality")
plot_centrality_with_colorbar(G_ce, pos_ce, btw_ce,
"C. elegans: Betweenness Centrality")
!pip install powerlaw
Collecting powerlaw Obtaining dependency information for powerlaw from https://files.pythonhosted.org/packages/e8/26/e0daa306f83d705bc1ed4d6759b7fc945cc787530c230ee1fe299cc28093/powerlaw-1.5-py3-none-any.whl.metadata Downloading powerlaw-1.5-py3-none-any.whl.metadata (9.3 kB) Requirement already satisfied: scipy in c:\users\benja\anaconda3\lib\site-packages (from powerlaw) (1.10.1) Requirement already satisfied: numpy in c:\users\benja\anaconda3\lib\site-packages (from powerlaw) (1.24.3) Requirement already satisfied: matplotlib in c:\users\benja\anaconda3\lib\site-packages (from powerlaw) (3.7.1) Requirement already satisfied: mpmath in c:\users\benja\anaconda3\lib\site-packages (from powerlaw) (1.3.0) Requirement already satisfied: contourpy>=1.0.1 in c:\users\benja\anaconda3\lib\site-packages (from matplotlib->powerlaw) (1.0.5) Requirement already satisfied: cycler>=0.10 in c:\users\benja\anaconda3\lib\site-packages (from matplotlib->powerlaw) (0.11.0) Requirement already satisfied: fonttools>=4.22.0 in c:\users\benja\anaconda3\lib\site-packages (from matplotlib->powerlaw) (4.25.0) Requirement already satisfied: kiwisolver>=1.0.1 in c:\users\benja\anaconda3\lib\site-packages (from matplotlib->powerlaw) (1.4.4) Requirement already satisfied: packaging>=20.0 in c:\users\benja\anaconda3\lib\site-packages (from matplotlib->powerlaw) (23.0) Requirement already satisfied: pillow>=6.2.0 in c:\users\benja\anaconda3\lib\site-packages (from matplotlib->powerlaw) (9.4.0) Requirement already satisfied: pyparsing>=2.3.1 in c:\users\benja\anaconda3\lib\site-packages (from matplotlib->powerlaw) (3.0.9) Requirement already satisfied: python-dateutil>=2.7 in c:\users\benja\anaconda3\lib\site-packages (from matplotlib->powerlaw) (2.8.2) Requirement already satisfied: six>=1.5 in c:\users\benja\anaconda3\lib\site-packages (from python-dateutil>=2.7->matplotlib->powerlaw) (1.16.0) Downloading powerlaw-1.5-py3-none-any.whl (24 kB) Installing collected packages: powerlaw Successfully installed powerlaw-1.5
import networkx as nx
import powerlaw
import pandas as pd
import matplotlib.pyplot as plt
# 1) Carga el grafo dirigido y lo convierte a no dirigido para extraer la componente gigante
G_air = read_dir_graph_weighted('airport.txt')
G_air_und = G_air.to_undirected()
comp = max(nx.connected_components(G_air_und), key=len)
Gg_air = G_air_und.subgraph(comp).copy()
# 2) Calcula parámetros observados
n = Gg_air.number_of_nodes()
m = Gg_air.number_of_edges()
grado_medio_obs = 2 * m / n
m0 = int(round(grado_medio_obs / (2 - 1/n))) # m₀ para BA
# 3) Simulaciones de los tres modelos
repetitions = 100
data = []
for seed in range(repetitions):
d = {}
# — Barabasi–Albert —
G = nx.barabasi_albert_graph(n, m0, seed=seed)
d['ba_avg_clus'] = nx.average_clustering(G)
d['ba_avg_dist'] = nx.average_shortest_path_length(G)
d['ba_avg_degree'] = 2 * G.number_of_edges() / n
d['ba_alpha'] = powerlaw.Fit(
[deg for _, deg in G.degree()],
discrete=True,
xmin=8
).alpha
# — Erdos–Rényi —
G = nx.gnm_random_graph(n, m, seed=seed)
d['er_avg_clus'] = nx.average_clustering(G)
d['er_avg_dist'] = nx.average_shortest_path_length(G)
d['er_avg_degree'] = 2 * G.number_of_edges() / n
# — Watts–Strogatz —
k = int(round(grado_medio_obs))
G = nx.watts_strogatz_graph(n, k, 0.03, seed=seed)
d['ws_avg_clus'] = nx.average_clustering(G)
d['ws_avg_dist'] = nx.average_shortest_path_length(G)
d['ws_avg_degree'] = 2 * G.number_of_edges() / n
data.append(d)
df = pd.DataFrame(data)
# 4) Valores reales de la componente gigante
valores_reales = {
'avg_clus': nx.average_clustering(Gg_air),
'avg_dist': nx.average_shortest_path_length(Gg_air),
'avg_degree': grado_medio_obs
}
# 5) Gráficos 3×3 comparando distribuciones y valor observado
fig, axs = plt.subplots(3, 3, figsize=(15, 12))
indicadores = ['avg_clus', 'avg_dist', 'avg_degree']
modelos = ['ba', 'er', 'ws']
for i, ind in enumerate(indicadores):
for j, model in enumerate(modelos):
ax = axs[i, j]
col = f'{model}_{ind}'
df[col].hist(ax=ax, density=True, bins=30)
ax.axvline(valores_reales[ind], color='r', linewidth=2)
ax.set_title(f'{model.upper()} – {ind}')
plt.tight_layout()
plt.show()
df = pd.DataFrame(data)
plt.plot(df['ba_avg_dist'].values,df['ba_avg_clus'].values,'ro',label='BA')
plt.plot(df['er_avg_dist'].values,df['er_avg_clus'].values,'bo',label='ER')
plt.plot(df['ws_avg_dist'].values,df['ws_avg_clus'].values,'go',label='WS')
plt.plot(nx.average_shortest_path_length(Gg_air),nx.average_clustering(Gg_air),'ko',label='air')
plt.legend()
plt.ylabel('Clustering medio')
plt.xlabel('Minimo camino medio')
plt.show()
import networkx as nx
import powerlaw
import pandas as pd
import matplotlib.pyplot as plt
import urllib.request
# 2) Carga y componente gigante
G_ce = read_graph_weighted("celegans.txt")
G_ce_und = G_ce.to_undirected()
comp = max(nx.connected_components(G_ce_und), key=len)
Gg_ce = G_ce_und.subgraph(comp).copy()
# 3) Parámetros observados
n = Gg_ce.number_of_nodes()
m = Gg_ce.number_of_edges()
grado_medio_obs = 2 * m / n
m0 = int(round(grado_medio_obs / (2 - 1/n))) # para BA
print(f"C. elegans: n={n}, m={m}, ⟨k⟩={grado_medio_obs:.2f}, m0={m0}")
# 4) Simulaciones
repetitions = 50 # <–– baja de 100 a 50 para ganar velocidad
data = []
for seed in range(repetitions):
d = {}
# — Barabasi–Albert
G = nx.barabasi_albert_graph(n, m0, seed=seed)
d['ba_avg_clus'] = nx.average_clustering(G)
d['ba_avg_dist'] = nx.average_shortest_path_length(G)
d['ba_avg_degree'] = 2 * G.number_of_edges() / n
# alpha solo en BA
degs = [deg for _, deg in G.degree()]
d['ba_alpha'] = powerlaw.Fit(degs, discrete=True, xmin=2).alpha
# — Erdos–Rényi
G = nx.gnm_random_graph(n, m, seed=seed)
d['er_avg_clus'] = nx.average_clustering(G)
d['er_avg_dist'] = nx.average_shortest_path_length(G)
d['er_avg_degree'] = 2 * G.number_of_edges() / n
# — Watts–Strogatz
k = int(round(grado_medio_obs))
G = nx.watts_strogatz_graph(n, k, 0.03, seed=seed)
d['ws_avg_clus'] = nx.average_clustering(G)
d['ws_avg_dist'] = nx.average_shortest_path_length(G)
d['ws_avg_degree'] = 2 * G.number_of_edges() / n
data.append(d)
df = pd.DataFrame(data)
# 5) Valores reales
valores_reales = {
'avg_clus': nx.average_clustering(Gg_ce),
'avg_dist': nx.average_shortest_path_length(Gg_ce),
'avg_degree': grado_medio_obs
}
# 6) Gráficos 3×3
fig, axs = plt.subplots(3, 3, figsize=(15, 12))
indicadores = ['avg_clus', 'avg_dist', 'avg_degree']
modelos = ['ba', 'er', 'ws']
for i, ind in enumerate(indicadores):
for j, model in enumerate(modelos):
ax = axs[i, j]
col = f'{model}_{ind}'
df[col].hist(ax=ax, density=True, bins=25)
ax.axvline(valores_reales[ind], color='r', lw=2)
ax.set_title(f'{model.upper()} – {ind}')
plt.tight_layout()
# 7) Scatter clustering vs. dist
fig2, ax2 = plt.subplots(figsize=(6, 5))
ax2.plot(df['ba_avg_dist'], df['ba_avg_clus'], 'ro', label='BA')
ax2.plot(df['er_avg_dist'], df['er_avg_clus'], 'bo', label='ER')
ax2.plot(df['ws_avg_dist'], df['ws_avg_clus'], 'go', label='WS')
ax2.plot(valores_reales['avg_dist'], valores_reales['avg_clus'], 'ko', label='obs')
ax2.set_xlabel('Camino medio')
ax2.set_ylabel('Clustering medio')
ax2.legend()
plt.show()
C. elegans: n=297, m=2148, ⟨k⟩=14.46, m0=7
import networkx as nx
import matplotlib.pyplot as plt
import pickle
def plot_centrality(G, pos, centrality, title, cmap=plt.cm.plasma):
"""
Dibuja G usando 'pos', coloreando y escalando nodos según 'centrality'.
"""
vals = list(centrality.values())
# normalizar colores entre 0 y 1
norm = [(v - min(vals)) / (max(vals) - min(vals) + 1e-6) for v in vals]
# escalas de tamaño (entre 100 y 1000)
sizes = [100 + 900 * x for x in norm]
nx.draw_networkx_nodes(G, pos,
node_size=sizes,
node_color=vals,
cmap=cmap)
nx.draw_networkx_edges(G, pos, alpha=0.3)
plt.title(title)
plt.axis('off')
# --- 1) Grafo dirigido: Airport (componente fuertemente conexa) ---
G_air = read_dir_graph_weighted('airport.txt')
H_air = obtener_mayor_componente_fuertemente_conexa(G_air)
with open('airportStronglyConn_pos.pkl','rb') as f:
pos_air = pickle.load(f)
# Centralidades
deg_air = nx.degree_centrality(H_air) # grado (in+out normalizado)
pr_air = nx.pagerank(H_air, weight='weight')
plt.figure(figsize=(12,5))
plt.subplot(1,2,1)
plot_centrality(H_air, pos_air, deg_air, "Airport: Degree Centrality")
plt.subplot(1,2,2)
plot_centrality(H_air, pos_air, pr_air, "Airport: PageRank")
plt.show()
# --- 2) Grafo no dirigido: C. elegans ---
G_ce = read_graph_weighted('celegans.txt')
pos_ce = nx.spring_layout(G_ce, iterations=1000, seed=42)
# Centralidades
deg_ce = nx.degree_centrality(G_ce)
btw_ce = nx.betweenness_centrality(G_ce, weight='weight', normalized=True)
plt.figure(figsize=(12,5))
plt.subplot(1,2,1)
plot_centrality(G_ce, pos_ce, deg_ce, "C. elegans: Degree Centrality")
plt.subplot(1,2,2)
plot_centrality(G_ce, pos_ce, btw_ce, "C. elegans: Betweenness")
plt.show()
import networkx as nx
import pandas as pd
# 1) Carga y extrae componente gigante
G_air = read_dir_graph_weighted('airport.txt')
G_air_und = G_air.to_undirected()
comp = max(nx.connected_components(G_air_und), key=len)
# Grafo para degree-centrality (no dirigido)
Gg_und = G_air_und.subgraph(comp).copy()
# Grafo para pagerank (dirigido, restringido a la misma compon.)
Gg_dir = G_air.subgraph(comp).copy()
# 2) Calcula centralidades
deg_cent = nx.degree_centrality(Gg_und)
pr = nx.pagerank(Gg_dir, alpha=0.85)
# 3) Monta DataFrame y ordena por degree centrality
df = pd.DataFrame([
{'airport': n,
'degree_centrality': deg_cent[n],
'pagerank': pr.get(n, 0)}
for n in Gg_und.nodes()
])
df = df.sort_values('degree_centrality', ascending=False).reset_index(drop=True)
# 4) Imprime el resultado
print(df.to_string(index=False, float_format='%.4f'))
airport degree_centrality pagerank
45 0.1999 0.0366
68 0.1903 0.0105
87 0.1884 0.0281
164 0.1859 0.0256
73 0.1852 0.0225
146 0.1744 0.0240
149 0.1738 0.0150
173 0.1712 0.0161
158 0.1700 0.0179
316 0.1661 0.0168
56 0.1617 0.0229
59 0.1604 0.0137
132 0.1560 0.0122
89 0.1553 0.0125
163 0.1528 0.0164
79 0.1470 0.0142
135 0.1394 0.0033
195 0.1362 0.0169
61 0.1343 0.0096
9 0.1305 0.0043
50 0.1299 0.0035
53 0.1292 0.0039
136 0.1286 0.0087
105 0.1260 0.0048
54 0.1248 0.0150
82 0.1241 0.0042
91 0.1241 0.0031
194 0.1229 0.0225
176 0.1229 0.0019
182 0.1209 0.0162
81 0.1203 0.0048
187 0.1203 0.0035
145 0.1190 0.0070
76 0.1190 0.0094
71 0.1171 0.0031
78 0.1171 0.0042
112 0.1165 0.0099
101 0.1146 0.0051
137 0.1146 0.0024
174 0.1120 0.0033
127 0.1120 0.0034
193 0.1101 0.0015
80 0.1101 0.0065
31 0.1095 0.0222
190 0.1076 0.0030
48 0.1057 0.0012
177 0.1057 0.0017
202 0.1050 0.0064
128 0.1038 0.0021
142 0.1031 0.0033
229 0.1012 0.0021
181 0.0980 0.0071
102 0.0980 0.0011
134 0.0974 0.0021
110 0.0948 0.0004
58 0.0936 0.0009
77 0.0936 0.0009
239 0.0923 0.0008
124 0.0910 0.0014
189 0.0910 0.0071
179 0.0898 0.0013
94 0.0891 0.0015
175 0.0885 0.0043
185 0.0878 0.0016
196 0.0872 0.0037
188 0.0866 0.0018
203 0.0847 0.0015
69 0.0847 0.0007
103 0.0840 0.0002
55 0.0840 0.0011
123 0.0834 0.0027
21 0.0834 0.0074
72 0.0834 0.0021
84 0.0827 0.0007
199 0.0815 0.0036
257 0.0802 0.0010
464 0.0783 0.0006
198 0.0783 0.0039
178 0.0777 0.0022
107 0.0770 0.0012
139 0.0770 0.0008
75 0.0764 0.0006
273 0.0757 0.0009
144 0.0751 0.0029
156 0.0751 0.0034
51 0.0738 0.0008
349 0.0732 0.0006
170 0.0713 0.0011
180 0.0713 0.0029
96 0.0707 0.0030
66 0.0707 0.0006
67 0.0707 0.0005
131 0.0700 0.0014
271 0.0694 0.0007
258 0.0694 0.0008
151 0.0687 0.0016
375 0.0681 0.0005
270 0.0668 0.0011
211 0.0662 0.0013
475 0.0649 0.0005
83 0.0643 0.0005
85 0.0643 0.0009
249 0.0637 0.0007
64 0.0637 0.0006
248 0.0637 0.0006
204 0.0637 0.0022
272 0.0637 0.0045
244 0.0630 0.0009
268 0.0624 0.0008
353 0.0617 0.0005
43 0.0617 0.0004
65 0.0617 0.0004
571 0.0605 0.0008
201 0.0598 0.0004
618 0.0598 0.0005
52 0.0592 0.0006
417 0.0592 0.0095
256 0.0554 0.0004
70 0.0547 0.0004
97 0.0535 0.0013
396 0.0528 0.0067
62 0.0528 0.0005
184 0.0528 0.0007
235 0.0516 0.0002
46 0.0509 0.0003
95 0.0490 0.0004
165 0.0484 0.0005
57 0.0484 0.0003
160 0.0477 0.0008
205 0.0477 0.0011
470 0.0477 0.0006
86 0.0477 0.0010
147 0.0471 0.0003
313 0.0465 0.0004
314 0.0465 0.0021
104 0.0458 0.0004
150 0.0458 0.0006
472 0.0458 0.0002
378 0.0452 0.0004
157 0.0452 0.0004
126 0.0446 0.0004
254 0.0446 0.0004
252 0.0439 0.0022
590 0.0439 0.0005
545 0.0439 0.0002
108 0.0433 0.0002
690 0.0426 0.0003
166 0.0426 0.0014
462 0.0426 0.0006
100 0.0420 0.0006
90 0.0414 0.0006
338 0.0407 0.0006
167 0.0407 0.0004
130 0.0401 0.0007
355 0.0395 0.0004
584 0.0388 0.0003
262 0.0382 0.0004
30 0.0382 0.0031
465 0.0382 0.0003
608 0.0382 0.0002
539 0.0382 0.0005
191 0.0382 0.0007
466 0.0376 0.0002
168 0.0376 0.0019
686 0.0376 0.0006
658 0.0369 0.0003
245 0.0369 0.0003
513 0.0350 0.0027
731 0.0350 0.0004
337 0.0350 0.0003
471 0.0350 0.0002
265 0.0344 0.0003
676 0.0344 0.0002
725 0.0344 0.0003
596 0.0344 0.0005
694 0.0337 0.0003
612 0.0325 0.0003
344 0.0325 0.0002
255 0.0325 0.0003
47 0.0325 0.0002
197 0.0318 0.0008
140 0.0318 0.0004
183 0.0318 0.0004
461 0.0318 0.0003
507 0.0312 0.0007
328 0.0312 0.0005
251 0.0312 0.0003
153 0.0312 0.0006
26 0.0306 0.0006
720 0.0306 0.0002
463 0.0306 0.0002
372 0.0299 0.0003
275 0.0299 0.0003
289 0.0299 0.0013
575 0.0293 0.0004
657 0.0293 0.0006
374 0.0293 0.0003
169 0.0293 0.0004
186 0.0286 0.0007
691 0.0280 0.0002
13 0.0280 0.0024
371 0.0274 0.0003
664 0.0274 0.0006
264 0.0274 0.0009
534 0.0274 0.0006
512 0.0267 0.0026
148 0.0267 0.0004
60 0.0261 0.0002
219 0.0261 0.0002
274 0.0261 0.0002
253 0.0261 0.0002
468 0.0255 0.0002
632 0.0255 0.0050
1 0.0255 0.0029
619 0.0255 0.0008
16 0.0248 0.0016
960 0.0248 0.0033
413 0.0248 0.0004
172 0.0242 0.0003
373 0.0236 0.0043
936 0.0236 0.0002
672 0.0236 0.0007
839 0.0236 0.0002
152 0.0236 0.0004
425 0.0236 0.0008
649 0.0229 0.0004
496 0.0229 0.0026
129 0.0229 0.0002
403 0.0229 0.0003
340 0.0229 0.0001
662 0.0223 0.0001
171 0.0223 0.0002
398 0.0223 0.0006
98 0.0223 0.0008
312 0.0223 0.0004
707 0.0223 0.0002
277 0.0216 0.0002
607 0.0216 0.0004
63 0.0216 0.0004
22 0.0210 0.0004
550 0.0210 0.0004
154 0.0210 0.0002
402 0.0210 0.0004
407 0.0210 0.0003
610 0.0210 0.0003
976 0.0204 0.0052
975 0.0204 0.0031
505 0.0204 0.0004
230 0.0197 0.0007
702 0.0197 0.0002
841 0.0197 0.0002
362 0.0191 0.0005
730 0.0191 0.0004
341 0.0191 0.0001
799 0.0191 0.0001
732 0.0191 0.0003
846 0.0191 0.0002
345 0.0185 0.0005
593 0.0185 0.0023
574 0.0185 0.0004
159 0.0185 0.0002
708 0.0185 0.0001
583 0.0185 0.0001
220 0.0185 0.0003
719 0.0185 0.0002
365 0.0178 0.0030
705 0.0178 0.0001
400 0.0178 0.0002
122 0.0178 0.0003
92 0.0178 0.0003
276 0.0178 0.0002
601 0.0178 0.0002
4 0.0172 0.0018
93 0.0172 0.0001
630 0.0172 0.0003
703 0.0172 0.0002
597 0.0172 0.0002
484 0.0172 0.0018
215 0.0172 0.0017
957 0.0172 0.0047
806 0.0172 0.0009
405 0.0172 0.0003
401 0.0172 0.0003
685 0.0172 0.0002
399 0.0172 0.0002
408 0.0165 0.0002
520 0.0165 0.0002
162 0.0165 0.0002
798 0.0165 0.0002
232 0.0165 0.0002
700 0.0165 0.0003
333 0.0165 0.0002
656 0.0165 0.0001
674 0.0165 0.0001
430 0.0159 0.0003
354 0.0159 0.0009
361 0.0159 0.0002
391 0.0159 0.0003
677 0.0159 0.0004
410 0.0159 0.0003
826 0.0159 0.0003
892 0.0159 0.0012
234 0.0159 0.0002
578 0.0159 0.0005
699 0.0153 0.0003
847 0.0153 0.0002
609 0.0153 0.0002
580 0.0153 0.0003
689 0.0153 0.0002
241 0.0153 0.0006
735 0.0153 0.0004
309 0.0153 0.0002
404 0.0153 0.0002
701 0.0153 0.0003
624 0.0153 0.0002
673 0.0153 0.0003
500 0.0146 0.0002
503 0.0146 0.0014
348 0.0146 0.0002
113 0.0146 0.0002
587 0.0146 0.0005
819 0.0146 0.0002
756 0.0146 0.0003
233 0.0146 0.0001
409 0.0146 0.0003
228 0.0146 0.0003
397 0.0146 0.0003
335 0.0146 0.0002
99 0.0146 0.0002
754 0.0140 0.0003
790 0.0140 0.0002
329 0.0140 0.0002
263 0.0140 0.0002
751 0.0140 0.0002
351 0.0140 0.0006
502 0.0140 0.0003
326 0.0140 0.0002
549 0.0134 0.0002
119 0.0134 0.0003
380 0.0134 0.0001
757 0.0134 0.0002
20 0.0134 0.0011
352 0.0134 0.0003
395 0.0134 0.0002
347 0.0134 0.0005
414 0.0134 0.0002
620 0.0134 0.0002
480 0.0134 0.0002
406 0.0134 0.0002
412 0.0134 0.0002
459 0.0134 0.0003
212 0.0134 0.0001
645 0.0134 0.0002
237 0.0127 0.0001
529 0.0127 0.0003
415 0.0127 0.0003
1033 0.0127 0.0002
650 0.0127 0.0008
827 0.0127 0.0003
336 0.0127 0.0002
759 0.0127 0.0002
688 0.0127 0.0002
325 0.0127 0.0002
634 0.0127 0.0002
278 0.0127 0.0002
525 0.0121 0.0002
331 0.0121 0.0002
832 0.0121 0.0014
746 0.0121 0.0006
748 0.0121 0.0001
648 0.0121 0.0002
383 0.0121 0.0001
670 0.0121 0.0003
238 0.0121 0.0001
305 0.0121 0.0002
783 0.0121 0.0004
626 0.0121 0.0009
882 0.0121 0.0002
617 0.0121 0.0002
871 0.0121 0.0002
568 0.0121 0.0004
716 0.0121 0.0002
115 0.0121 0.0002
32 0.0121 0.0002
842 0.0121 0.0001
88 0.0121 0.0002
225 0.0115 0.0003
613 0.0115 0.0009
515 0.0115 0.0001
655 0.0115 0.0006
627 0.0115 0.0019
236 0.0115 0.0001
49 0.0115 0.0005
427 0.0115 0.0002
421 0.0115 0.0002
222 0.0115 0.0004
559 0.0115 0.0001
292 0.0115 0.0008
639 0.0115 0.0009
853 0.0115 0.0006
592 0.0115 0.0005
367 0.0115 0.0007
589 0.0115 0.0002
14 0.0108 0.0003
581 0.0108 0.0003
524 0.0108 0.0002
431 0.0108 0.0002
526 0.0108 0.0002
411 0.0108 0.0002
640 0.0108 0.0006
487 0.0108 0.0002
106 0.0108 0.0002
663 0.0108 0.0007
116 0.0108 0.0002
516 0.0108 0.0006
504 0.0108 0.0002
121 0.0108 0.0002
791 0.0108 0.0001
727 0.0108 0.0002
473 0.0108 0.0001
579 0.0108 0.0003
810 0.0108 0.0001
733 0.0108 0.0002
1026 0.0108 0.0001
712 0.0108 0.0002
711 0.0108 0.0002
894 0.0102 0.0011
965 0.0102 0.0001
901 0.0102 0.0001
622 0.0102 0.0010
226 0.0102 0.0005
633 0.0102 0.0006
605 0.0102 0.0004
433 0.0102 0.0002
669 0.0102 0.0004
973 0.0102 0.0002
192 0.0102 0.0002
1098 0.0095 0.0002
332 0.0095 0.0001
424 0.0095 0.0001
243 0.0095 0.0002
426 0.0095 0.0002
339 0.0095 0.0006
117 0.0095 0.0002
718 0.0095 0.0001
850 0.0095 0.0001
671 0.0095 0.0001
322 0.0095 0.0007
1068 0.0095 0.0002
34 0.0095 0.0002
291 0.0095 0.0007
582 0.0089 0.0002
577 0.0089 0.0002
495 0.0089 0.0002
536 0.0089 0.0002
267 0.0089 0.0001
455 0.0089 0.0002
681 0.0089 0.0002
324 0.0089 0.0002
714 0.0089 0.0001
809 0.0089 0.0001
246 0.0089 0.0003
825 0.0089 0.0002
838 0.0089 0.0001
861 0.0089 0.0005
896 0.0089 0.0001
120 0.0089 0.0003
114 0.0089 0.0002
111 0.0089 0.0001
898 0.0089 0.0002
42 0.0089 0.0007
906 0.0089 0.0002
961 0.0089 0.0002
1097 0.0089 0.0002
1110 0.0089 0.0001
334 0.0089 0.0002
224 0.0089 0.0006
621 0.0089 0.0004
377 0.0089 0.0001
631 0.0089 0.0007
118 0.0083 0.0002
508 0.0083 0.0002
432 0.0083 0.0001
44 0.0083 0.0001
438 0.0083 0.0002
33 0.0083 0.0001
652 0.0083 0.0002
223 0.0083 0.0001
556 0.0083 0.0002
240 0.0083 0.0002
389 0.0083 0.0002
434 0.0083 0.0002
604 0.0083 0.0006
293 0.0083 0.0002
294 0.0083 0.0002
379 0.0083 0.0001
260 0.0083 0.0001
547 0.0083 0.0002
918 0.0076 0.0001
435 0.0076 0.0002
1105 0.0076 0.0001
1190 0.0076 0.0003
920 0.0076 0.0015
7 0.0076 0.0012
1006 0.0076 0.0008
1102 0.0076 0.0002
448 0.0076 0.0002
565 0.0076 0.0002
675 0.0076 0.0003
356 0.0076 0.0002
848 0.0076 0.0002
697 0.0076 0.0001
773 0.0076 0.0019
387 0.0076 0.0002
429 0.0076 0.0001
453 0.0076 0.0001
611 0.0076 0.0006
501 0.0076 0.0009
651 0.0076 0.0003
533 0.0076 0.0012
852 0.0070 0.0002
570 0.0070 0.0003
660 0.0070 0.0004
1016 0.0070 0.0001
857 0.0070 0.0002
569 0.0070 0.0002
747 0.0070 0.0002
745 0.0070 0.0016
667 0.0070 0.0004
1104 0.0070 0.0001
603 0.0070 0.0002
646 0.0070 0.0006
1121 0.0070 0.0001
925 0.0070 0.0001
786 0.0070 0.0001
510 0.0070 0.0002
390 0.0070 0.0002
321 0.0070 0.0003
444 0.0070 0.0001
213 0.0070 0.0001
392 0.0070 0.0002
776 0.0064 0.0003
769 0.0064 0.0001
419 0.0064 0.0006
519 0.0064 0.0002
792 0.0064 0.0001
303 0.0064 0.0002
350 0.0064 0.0003
692 0.0064 0.0001
514 0.0064 0.0002
706 0.0064 0.0001
320 0.0064 0.0002
330 0.0064 0.0001
599 0.0064 0.0002
553 0.0064 0.0002
643 0.0064 0.0003
954 0.0064 0.0007
951 0.0064 0.0013
962 0.0064 0.0001
966 0.0064 0.0001
1176 0.0064 0.0002
436 0.0064 0.0003
623 0.0064 0.0001
1030 0.0064 0.0001
454 0.0057 0.0001
388 0.0057 0.0002
661 0.0057 0.0002
682 0.0057 0.0002
477 0.0057 0.0001
606 0.0057 0.0006
625 0.0057 0.0002
2 0.0057 0.0003
428 0.0057 0.0001
637 0.0057 0.0001
1100 0.0057 0.0002
535 0.0057 0.0001
318 0.0057 0.0002
1357 0.0057 0.0001
948 0.0057 0.0001
937 0.0057 0.0001
972 0.0057 0.0001
109 0.0057 0.0001
1241 0.0057 0.0004
863 0.0057 0.0001
824 0.0057 0.0002
817 0.0057 0.0001
259 0.0057 0.0001
266 0.0057 0.0001
777 0.0057 0.0009
282 0.0057 0.0001
767 0.0057 0.0001
296 0.0057 0.0002
1207 0.0057 0.0002
739 0.0057 0.0001
738 0.0057 0.0004
1075 0.0057 0.0004
598 0.0057 0.0004
729 0.0057 0.0001
36 0.0057 0.0001
511 0.0057 0.0001
1157 0.0057 0.0003
1145 0.0057 0.0001
522 0.0057 0.0001
1159 0.0057 0.0002
1320 0.0051 0.0001
1267 0.0051 0.0003
327 0.0051 0.0001
74 0.0051 0.0001
509 0.0051 0.0005
638 0.0051 0.0002
812 0.0051 0.0001
247 0.0051 0.0001
909 0.0051 0.0002
680 0.0051 0.0003
1106 0.0051 0.0001
370 0.0051 0.0001
1010 0.0051 0.0001
1099 0.0051 0.0001
214 0.0051 0.0002
1310 0.0051 0.0002
385 0.0051 0.0001
1254 0.0051 0.0002
544 0.0051 0.0001
977 0.0051 0.0025
996 0.0051 0.0002
1407 0.0051 0.0001
133 0.0051 0.0001
35 0.0051 0.0001
1258 0.0051 0.0002
567 0.0051 0.0001
285 0.0051 0.0001
836 0.0051 0.0001
1317 0.0051 0.0001
287 0.0051 0.0003
835 0.0051 0.0001
876 0.0051 0.0002
1058 0.0045 0.0001
1138 0.0045 0.0001
734 0.0045 0.0001
913 0.0045 0.0001
1042 0.0045 0.0002
1046 0.0045 0.0001
758 0.0045 0.0001
710 0.0045 0.0001
855 0.0045 0.0002
1339 0.0045 0.0002
868 0.0045 0.0001
728 0.0045 0.0001
1298 0.0045 0.0006
1133 0.0045 0.0001
865 0.0045 0.0001
715 0.0045 0.0001
704 0.0045 0.0001
386 0.0045 0.0001
770 0.0045 0.0006
709 0.0045 0.0001
917 0.0045 0.0002
1060 0.0045 0.0002
815 0.0045 0.0001
828 0.0045 0.0002
1177 0.0045 0.0002
446 0.0045 0.0001
250 0.0045 0.0001
628 0.0045 0.0003
523 0.0045 0.0001
615 0.0045 0.0002
1117 0.0045 0.0002
29 0.0045 0.0001
1414 0.0045 0.0003
476 0.0045 0.0001
813 0.0045 0.0001
924 0.0045 0.0001
1039 0.0045 0.0001
814 0.0045 0.0001
1122 0.0045 0.0002
242 0.0038 0.0001
449 0.0038 0.0002
527 0.0038 0.0001
897 0.0038 0.0001
659 0.0038 0.0001
1439 0.0038 0.0001
558 0.0038 0.0001
552 0.0038 0.0001
1085 0.0038 0.0002
304 0.0038 0.0002
721 0.0038 0.0001
763 0.0038 0.0001
1398 0.0038 0.0001
1027 0.0038 0.0001
760 0.0038 0.0001
955 0.0038 0.0002
1203 0.0038 0.0001
1004 0.0038 0.0002
482 0.0038 0.0003
1421 0.0038 0.0003
899 0.0038 0.0001
678 0.0038 0.0007
494 0.0038 0.0001
381 0.0038 0.0001
269 0.0038 0.0001
1024 0.0038 0.0001
6 0.0038 0.0002
18 0.0038 0.0003
980 0.0038 0.0001
1182 0.0038 0.0006
423 0.0038 0.0002
506 0.0038 0.0001
210 0.0038 0.0001
585 0.0038 0.0003
346 0.0038 0.0003
971 0.0038 0.0003
687 0.0038 0.0001
1132 0.0038 0.0002
1213 0.0038 0.0002
854 0.0038 0.0001
161 0.0038 0.0001
1011 0.0032 0.0001
830 0.0032 0.0010
1044 0.0032 0.0001
753 0.0032 0.0002
283 0.0032 0.0001
209 0.0032 0.0001
829 0.0032 0.0001
1347 0.0032 0.0002
870 0.0032 0.0002
796 0.0032 0.0001
1038 0.0032 0.0001
1017 0.0032 0.0001
554 0.0032 0.0001
789 0.0032 0.0001
859 0.0032 0.0001
771 0.0032 0.0003
1032 0.0032 0.0001
811 0.0032 0.0001
1050 0.0032 0.0002
1029 0.0032 0.0001
768 0.0032 0.0001
823 0.0032 0.0001
1396 0.0032 0.0001
808 0.0032 0.0001
548 0.0032 0.0001
1012 0.0032 0.0003
231 0.0032 0.0001
866 0.0032 0.0001
816 0.0032 0.0001
1055 0.0032 0.0001
1028 0.0032 0.0001
644 0.0032 0.0001
939 0.0032 0.0001
990 0.0032 0.0001
343 0.0032 0.0001
586 0.0032 0.0001
1362 0.0032 0.0004
905 0.0032 0.0001
445 0.0032 0.0001
1179 0.0032 0.0001
359 0.0032 0.0001
910 0.0032 0.0001
1249 0.0032 0.0007
967 0.0032 0.0001
1103 0.0032 0.0001
635 0.0032 0.0001
1096 0.0032 0.0002
912 0.0032 0.0001
922 0.0032 0.0001
368 0.0032 0.0001
915 0.0032 0.0001
382 0.0032 0.0001
499 0.0032 0.0005
1493 0.0032 0.0001
498 0.0032 0.0001
696 0.0032 0.0001
1090 0.0032 0.0001
1239 0.0032 0.0002
930 0.0032 0.0001
1302 0.0032 0.0001
1162 0.0032 0.0001
1067 0.0032 0.0002
741 0.0032 0.0002
1005 0.0032 0.0001
602 0.0032 0.0003
647 0.0032 0.0001
537 0.0032 0.0002
952 0.0032 0.0002
884 0.0032 0.0001
978 0.0032 0.0002
963 0.0032 0.0001
531 0.0032 0.0001
1107 0.0032 0.0002
722 0.0032 0.0001
891 0.0032 0.0001
1083 0.0032 0.0001
717 0.0032 0.0001
315 0.0032 0.0001
994 0.0032 0.0003
944 0.0032 0.0001
1255 0.0025 0.0001
934 0.0025 0.0001
1303 0.0025 0.0001
1147 0.0025 0.0004
1158 0.0025 0.0001
942 0.0025 0.0001
945 0.0025 0.0001
947 0.0025 0.0001
538 0.0025 0.0002
956 0.0025 0.0012
964 0.0025 0.0001
208 0.0025 0.0001
1025 0.0025 0.0001
19 0.0025 0.0001
879 0.0025 0.0001
1001 0.0025 0.0003
141 0.0025 0.0001
1305 0.0025 0.0001
885 0.0025 0.0001
1240 0.0025 0.0002
867 0.0025 0.0001
1242 0.0025 0.0001
993 0.0025 0.0001
992 0.0025 0.0002
1226 0.0025 0.0001
543 0.0025 0.0002
856 0.0025 0.0001
1247 0.0025 0.0001
206 0.0025 0.0001
1225 0.0025 0.0001
1309 0.0025 0.0001
872 0.0025 0.0001
927 0.0025 0.0003
928 0.0025 0.0001
1219 0.0025 0.0003
532 0.0025 0.0001
138 0.0025 0.0001
1411 0.0025 0.0001
218 0.0025 0.0002
1166 0.0025 0.0001
376 0.0025 0.0001
1531 0.0025 0.0001
366 0.0025 0.0001
364 0.0025 0.0001
683 0.0025 0.0001
360 0.0025 0.0001
358 0.0025 0.0001
1184 0.0025 0.0002
695 0.0025 0.0001
572 0.0025 0.0002
1072 0.0025 0.0001
1318 0.0025 0.0001
317 0.0025 0.0002
1192 0.0025 0.0001
1084 0.0025 0.0001
1081 0.0025 0.0001
1080 0.0025 0.0002
302 0.0025 0.0001
566 0.0025 0.0001
1078 0.0025 0.0001
666 0.0025 0.0001
497 0.0025 0.0002
394 0.0025 0.0001
416 0.0025 0.0003
485 0.0025 0.0001
595 0.0025 0.0001
594 0.0025 0.0001
474 0.0025 0.0001
456 0.0025 0.0001
452 0.0025 0.0001
1422 0.0025 0.0002
591 0.0025 0.0002
489 0.0025 0.0001
447 0.0025 0.0005
629 0.0025 0.0003
1109 0.0025 0.0003
1429 0.0025 0.0002
642 0.0025 0.0001
491 0.0025 0.0001
420 0.0025 0.0001
1372 0.0025 0.0003
654 0.0025 0.0001
1430 0.0025 0.0001
1073 0.0025 0.0001
1137 0.0025 0.0001
1036 0.0025 0.0001
755 0.0025 0.0001
780 0.0025 0.0001
563 0.0025 0.0001
1161 0.0025 0.0001
1342 0.0025 0.0002
774 0.0025 0.0003
772 0.0025 0.0003
766 0.0025 0.0001
1040 0.0025 0.0001
765 0.0025 0.0001
764 0.0025 0.0001
1344 0.0025 0.0001
1056 0.0025 0.0001
805 0.0025 0.0002
1048 0.0025 0.0001
227 0.0025 0.0001
1065 0.0025 0.0001
221 0.0025 0.0001
562 0.0025 0.0001
1209 0.0025 0.0002
560 0.0025 0.0001
958 0.0025 0.0003
1116 0.0019 0.0001
1256 0.0019 0.0001
1108 0.0019 0.0003
17 0.0019 0.0001
1123 0.0019 0.0002
969 0.0019 0.0001
1045 0.0019 0.0001
1047 0.0019 0.0001
1222 0.0019 0.0002
1128 0.0019 0.0001
1112 0.0019 0.0001
1043 0.0019 0.0001
1181 0.0019 0.0002
1118 0.0019 0.0001
1172 0.0019 0.0003
1160 0.0019 0.0001
1037 0.0019 0.0001
1120 0.0019 0.0001
1170 0.0019 0.0001
1035 0.0019 0.0001
1144 0.0019 0.0001
1174 0.0019 0.0001
1034 0.0019 0.0001
1071 0.0019 0.0001
979 0.0019 0.0001
1216 0.0019 0.0001
991 0.0019 0.0001
1000 0.0019 0.0002
1200 0.0019 0.0001
1518 0.0019 0.0001
1007 0.0019 0.0001
1079 0.0019 0.0001
1208 0.0019 0.0001
1520 0.0019 0.0001
1212 0.0019 0.0001
1186 0.0019 0.0001
1057 0.0019 0.0001
1164 0.0019 0.0001
1092 0.0019 0.0001
988 0.0019 0.0001
1019 0.0019 0.0001
1244 0.0019 0.0003
985 0.0019 0.0001
1094 0.0019 0.0001
1228 0.0019 0.0001
1141 0.0019 0.0001
982 0.0019 0.0001
1250 0.0019 0.0001
1101 0.0019 0.0001
1125 0.0019 0.0001
1053 0.0019 0.0001
1051 0.0019 0.0001
1506 0.0019 0.0001
1063 0.0019 0.0003
843 0.0019 0.0001
953 0.0019 0.0001
1260 0.0019 0.0002
1358 0.0019 0.0001
726 0.0019 0.0001
297 0.0019 0.0001
1355 0.0019 0.0001
737 0.0019 0.0002
740 0.0019 0.0001
742 0.0019 0.0001
1354 0.0019 0.0001
1469 0.0019 0.0001
288 0.0019 0.0001
750 0.0019 0.0001
1470 0.0019 0.0001
784 0.0019 0.0003
1447 0.0019 0.0001
785 0.0019 0.0001
1476 0.0019 0.0002
788 0.0019 0.0001
1330 0.0019 0.0001
797 0.0019 0.0001
261 0.0019 0.0001
803 0.0019 0.0001
807 0.0019 0.0002
1316 0.0019 0.0001
1481 0.0019 0.0001
207 0.0019 0.0001
1308 0.0019 0.0001
1448 0.0019 0.0001
1359 0.0019 0.0001
1307 0.0019 0.0002
478 0.0019 0.0001
541 0.0019 0.0001
528 0.0019 0.0001
551 0.0019 0.0001
1385 0.0019 0.0001
561 0.0019 0.0001
1379 0.0019 0.0004
1400 0.0019 0.0002
576 0.0019 0.0001
493 0.0019 0.0001
588 0.0019 0.0001
490 0.0019 0.0007
479 0.0019 0.0001
1417 0.0019 0.0002
1361 0.0019 0.0001
614 0.0019 0.0001
1376 0.0019 0.0004
442 0.0019 0.0001
1427 0.0019 0.0001
1373 0.0019 0.0002
437 0.0019 0.0005
422 0.0019 0.0004
393 0.0019 0.0001
665 0.0019 0.0001
384 0.0019 0.0001
369 0.0019 0.0001
357 0.0019 0.0001
1482 0.0019 0.0001
778 0.0019 0.0001
860 0.0019 0.0001
125 0.0019 0.0001
1300 0.0019 0.0001
1490 0.0019 0.0001
932 0.0019 0.0001
877 0.0019 0.0001
1273 0.0019 0.0001
878 0.0019 0.0001
880 0.0019 0.0001
1297 0.0019 0.0001
874 0.0019 0.0001
1290 0.0019 0.0001
926 0.0019 0.0001
923 0.0019 0.0001
881 0.0019 0.0001
890 0.0019 0.0001
883 0.0019 0.0001
1299 0.0019 0.0001
1270 0.0019 0.0001
1271 0.0019 0.0001
900 0.0019 0.0001
943 0.0019 0.0001
1283 0.0019 0.0001
1306 0.0019 0.0002
903 0.0019 0.0001
864 0.0019 0.0001
1286 0.0019 0.0001
155 0.0019 0.0001
1263 0.0019 0.0002
1264 0.0019 0.0002
1435 0.0013 0.0001
1370 0.0013 0.0001
1288 0.0013 0.0001
1539 0.0013 0.0007
1248 0.0013 0.0001
1375 0.0013 0.0001
1279 0.0013 0.0001
1569 0.0013 0.0001
1281 0.0013 0.0001
1371 0.0013 0.0002
1428 0.0013 0.0001
1280 0.0013 0.0001
1562 0.0013 0.0001
1566 0.0013 0.0001
1425 0.0013 0.0001
1413 0.0013 0.0001
1178 0.0013 0.0002
1423 0.0013 0.0002
1389 0.0013 0.0001
1261 0.0013 0.0001
1388 0.0013 0.0003
1394 0.0013 0.0001
1387 0.0013 0.0001
1382 0.0013 0.0001
1498 0.0013 0.0002
1163 0.0013 0.0001
1269 0.0013 0.0001
1496 0.0013 0.0001
1378 0.0013 0.0003
1153 0.0013 0.0001
1167 0.0013 0.0001
1168 0.0013 0.0001
1169 0.0013 0.0001
1405 0.0013 0.0001
1409 0.0013 0.0001
1377 0.0013 0.0001
1175 0.0013 0.0001
1412 0.0013 0.0001
1274 0.0013 0.0001
1501 0.0013 0.0001
1420 0.0013 0.0001
1503 0.0013 0.0001
1495 0.0013 0.0001
1366 0.0013 0.0001
1444 0.0013 0.0001
1438 0.0013 0.0001
1340 0.0013 0.0001
1475 0.0013 0.0001
1509 0.0013 0.0001
1334 0.0013 0.0001
1479 0.0013 0.0004
1333 0.0013 0.0001
1233 0.0013 0.0001
1329 0.0013 0.0001
1217 0.0013 0.0001
1231 0.0013 0.0001
1328 0.0013 0.0001
1327 0.0013 0.0001
1326 0.0013 0.0001
1488 0.0013 0.0001
1325 0.0013 0.0001
1323 0.0013 0.0001
1218 0.0013 0.0001
1322 0.0013 0.0001
1321 0.0013 0.0001
1230 0.0013 0.0001
1315 0.0013 0.0001
1480 0.0013 0.0001
1229 0.0013 0.0001
1312 0.0013 0.0001
1311 0.0013 0.0001
1224 0.0013 0.0001
1214 0.0013 0.0001
1341 0.0013 0.0001
1185 0.0013 0.0001
1237 0.0013 0.0001
1489 0.0013 0.0001
1440 0.0013 0.0001
1187 0.0013 0.0001
1442 0.0013 0.0001
1291 0.0013 0.0001
1243 0.0013 0.0001
1193 0.0013 0.0002
1449 0.0013 0.0001
1293 0.0013 0.0001
1451 0.0013 0.0001
1197 0.0013 0.0003
1455 0.0013 0.0001
1456 0.0013 0.0001
1201 0.0013 0.0001
1457 0.0013 0.0001
1296 0.0013 0.0001
1205 0.0013 0.0001
1206 0.0013 0.0001
1350 0.0013 0.0001
1459 0.0013 0.0001
1301 0.0013 0.0001
1348 0.0013 0.0001
1238 0.0013 0.0001
1473 0.0013 0.0001
1346 0.0013 0.0001
1155 0.0013 0.0001
0 0.0013 0.0001
693 0.0013 0.0001
1008 0.0013 0.0001
25 0.0013 0.0001
787 0.0013 0.0001
782 0.0013 0.0001
781 0.0013 0.0001
779 0.0013 0.0001
775 0.0013 0.0001
989 0.0013 0.0001
319 0.0013 0.0001
323 0.0013 0.0001
999 0.0013 0.0001
12 0.0013 0.0001
744 0.0013 0.0001
970 0.0013 0.0001
1014 0.0013 0.0001
743 0.0013 0.0002
736 0.0013 0.0001
1021 0.0013 0.0002
418 0.0013 0.0001
1031 0.0013 0.0001
1041 0.0013 0.0001
1049 0.0013 0.0001
698 0.0013 0.0002
1151 0.0013 0.0005
1054 0.0013 0.0001
974 0.0013 0.0001
968 0.0013 0.0001
684 0.0013 0.0001
921 0.0013 0.0008
889 0.0013 0.0001
875 0.0013 0.0002
873 0.0013 0.0001
869 0.0013 0.0001
845 0.0013 0.0001
280 0.0013 0.0001
844 0.0013 0.0002
911 0.0013 0.0001
914 0.0013 0.0001
298 0.0013 0.0001
916 0.0013 0.0001
833 0.0013 0.0001
793 0.0013 0.0001
929 0.0013 0.0001
41 0.0013 0.0001
820 0.0013 0.0001
306 0.0013 0.0001
940 0.0013 0.0001
307 0.0013 0.0001
802 0.0013 0.0008
941 0.0013 0.0001
800 0.0013 0.0002
795 0.0013 0.0001
794 0.0013 0.0001
1059 0.0013 0.0003
1018 0.0013 0.0002
1111 0.0013 0.0001
460 0.0013 0.0001
1087 0.0013 0.0003
557 0.0013 0.0001
1089 0.0013 0.0002
1091 0.0013 0.0002
1093 0.0013 0.0001
1114 0.0013 0.0001
546 0.0013 0.0001
1119 0.0013 0.0001
1124 0.0013 0.0001
542 0.0013 0.0001
540 0.0013 0.0001
1127 0.0013 0.0001
1129 0.0013 0.0001
1131 0.0013 0.0001
1134 0.0013 0.0001
488 0.0013 0.0001
5 0.0013 0.0003
1139 0.0013 0.0001
530 0.0013 0.0001
1142 0.0013 0.0002
1148 0.0013 0.0001
518 0.0013 0.0001
1150 0.0013 0.0003
564 0.0013 0.0001
888 0.0013 0.0001
457 0.0013 0.0001
1066 0.0013 0.0001
679 0.0013 0.0001
636 0.0013 0.0001
1082 0.0013 0.0001
653 0.0013 0.0001
600 0.0013 0.0001
10 0.0013 0.0001
641 0.0013 0.0002
668 0.0013 0.0001
1077 0.0013 0.0001
299 0.0006 0.0001
1434 0.0006 0.0001
300 0.0006 0.0001
458 0.0006 0.0001
1454 0.0006 0.0001
1453 0.0006 0.0001
1452 0.0006 0.0001
1426 0.0006 0.0001
1408 0.0006 0.0001
295 0.0006 0.0001
1458 0.0006 0.0001
486 0.0006 0.0001
1406 0.0006 0.0001
492 0.0006 0.0001
1460 0.0006 0.0001
1461 0.0006 0.0001
1462 0.0006 0.0001
1463 0.0006 0.0001
1404 0.0006 0.0001
1464 0.0006 0.0001
443 0.0006 0.0001
1424 0.0006 0.0001
1403 0.0006 0.0001
301 0.0006 0.0001
1410 0.0006 0.0001
1450 0.0006 0.0001
310 0.0006 0.0001
1436 0.0006 0.0001
1437 0.0006 0.0001
342 0.0006 0.0001
1416 0.0006 0.0001
1415 0.0006 0.0001
1433 0.0006 0.0001
1432 0.0006 0.0001
1418 0.0006 0.0001
1431 0.0006 0.0001
1441 0.0006 0.0001
311 0.0006 0.0001
1443 0.0006 0.0001
467 0.0006 0.0001
441 0.0006 0.0001
469 0.0006 0.0001
450 0.0006 0.0001
481 0.0006 0.0001
483 0.0006 0.0001
1445 0.0006 0.0001
1446 0.0006 0.0001
1465 0.0006 0.0001
1419 0.0006 0.0001
308 0.0006 0.0001
439 0.0006 0.0001
440 0.0006 0.0001
363 0.0006 0.0001
451 0.0006 0.0001
1484 0.0006 0.0001
1466 0.0006 0.0001
1535 0.0006 0.0001
1546 0.0006 0.0001
1545 0.0006 0.0001
1544 0.0006 0.0001
1543 0.0006 0.0001
1542 0.0006 0.0001
1541 0.0006 0.0001
1540 0.0006 0.0001
1538 0.0006 0.0007
1537 0.0006 0.0001
1536 0.0006 0.0001
1534 0.0006 0.0002
1467 0.0006 0.0001
1533 0.0006 0.0001
1532 0.0006 0.0001
11 0.0006 0.0001
1530 0.0006 0.0001
1529 0.0006 0.0001
1528 0.0006 0.0001
1527 0.0006 0.0001
1526 0.0006 0.0001
1525 0.0006 0.0001
1524 0.0006 0.0001
1547 0.0006 0.0001
1548 0.0006 0.0001
1549 0.0006 0.0001
1550 0.0006 0.0001
1572 0.0006 0.0001
1571 0.0006 0.0001
1570 0.0006 0.0001
3 0.0006 0.0001
1568 0.0006 0.0001
1567 0.0006 0.0001
1565 0.0006 0.0002
1564 0.0006 0.0001
1563 0.0006 0.0001
8 0.0006 0.0001
1561 0.0006 0.0001
1560 0.0006 0.0001
1559 0.0006 0.0001
1558 0.0006 0.0001
1557 0.0006 0.0001
1556 0.0006 0.0001
1555 0.0006 0.0001
1554 0.0006 0.0001
1553 0.0006 0.0001
1552 0.0006 0.0001
1551 0.0006 0.0001
1523 0.0006 0.0001
1522 0.0006 0.0001
1521 0.0006 0.0001
1494 0.0006 0.0001
1492 0.0006 0.0001
1491 0.0006 0.0001
40 0.0006 0.0001
143 0.0006 0.0001
1485 0.0006 0.0001
1401 0.0006 0.0001
1483 0.0006 0.0001
200 0.0006 0.0001
216 0.0006 0.0001
217 0.0006 0.0001
279 0.0006 0.0001
1478 0.0006 0.0003
1477 0.0006 0.0001
281 0.0006 0.0001
1474 0.0006 0.0001
284 0.0006 0.0001
1472 0.0006 0.0001
1471 0.0006 0.0001
286 0.0006 0.0001
290 0.0006 0.0001
1468 0.0006 0.0001
39 0.0006 0.0001
38 0.0006 0.0001
1519 0.0006 0.0001
37 0.0006 0.0001
15 0.0006 0.0001
1517 0.0006 0.0001
1516 0.0006 0.0001
1515 0.0006 0.0001
1514 0.0006 0.0001
1513 0.0006 0.0001
1512 0.0006 0.0001
1511 0.0006 0.0001
1510 0.0006 0.0001
23 0.0006 0.0001
1508 0.0006 0.0001
1507 0.0006 0.0001
24 0.0006 0.0001
1505 0.0006 0.0001
1504 0.0006 0.0001
1502 0.0006 0.0001
27 0.0006 0.0001
1500 0.0006 0.0001
1499 0.0006 0.0001
28 0.0006 0.0001
1497 0.0006 0.0001
1402 0.0006 0.0001
1152 0.0006 0.0005
517 0.0006 0.0001
1234 0.0006 0.0001
987 0.0006 0.0001
995 0.0006 0.0001
997 0.0006 0.0001
998 0.0006 0.0001
1002 0.0006 0.0001
1003 0.0006 0.0001
1236 0.0006 0.0001
1235 0.0006 0.0001
1232 0.0006 0.0001
1023 0.0006 0.0001
1009 0.0006 0.0001
1013 0.0006 0.0001
1015 0.0006 0.0001
1227 0.0006 0.0002
1020 0.0006 0.0001
1223 0.0006 0.0001
1022 0.0006 0.0001
1221 0.0006 0.0001
1245 0.0006 0.0001
1246 0.0006 0.0002
986 0.0006 0.0001
984 0.0006 0.0001
935 0.0006 0.0001
938 0.0006 0.0001
1268 0.0006 0.0001
1266 0.0006 0.0001
1265 0.0006 0.0001
946 0.0006 0.0001
1262 0.0006 0.0001
949 0.0006 0.0001
950 0.0006 0.0001
1259 0.0006 0.0001
959 0.0006 0.0001
1257 0.0006 0.0001
1253 0.0006 0.0001
1252 0.0006 0.0001
1251 0.0006 0.0001
981 0.0006 0.0001
983 0.0006 0.0001
1220 0.0006 0.0001
1215 0.0006 0.0001
1399 0.0006 0.0001
1130 0.0006 0.0001
1183 0.0006 0.0001
1095 0.0006 0.0001
1180 0.0006 0.0001
1113 0.0006 0.0001
1115 0.0006 0.0001
1126 0.0006 0.0001
1173 0.0006 0.0001
1171 0.0006 0.0002
1135 0.0006 0.0001
1052 0.0006 0.0001
1165 0.0006 0.0001
1136 0.0006 0.0001
1140 0.0006 0.0001
1143 0.0006 0.0001
1146 0.0006 0.0002
1149 0.0006 0.0002
1156 0.0006 0.0001
1154 0.0006 0.0001
1088 0.0006 0.0001
1188 0.0006 0.0001
1189 0.0006 0.0001
1191 0.0006 0.0001
1211 0.0006 0.0001
1210 0.0006 0.0001
1061 0.0006 0.0001
1062 0.0006 0.0001
1064 0.0006 0.0001
1069 0.0006 0.0001
1204 0.0006 0.0001
1070 0.0006 0.0001
1202 0.0006 0.0001
1074 0.0006 0.0001
1076 0.0006 0.0001
1199 0.0006 0.0001
1198 0.0006 0.0001
1196 0.0006 0.0001
1195 0.0006 0.0001
1194 0.0006 0.0001
1086 0.0006 0.0002
933 0.0006 0.0001
1272 0.0006 0.0001
931 0.0006 0.0001
1351 0.0006 0.0001
1363 0.0006 0.0002
1360 0.0006 0.0001
713 0.0006 0.0001
723 0.0006 0.0001
724 0.0006 0.0001
1356 0.0006 0.0001
1353 0.0006 0.0001
1352 0.0006 0.0001
1349 0.0006 0.0001
1275 0.0006 0.0001
749 0.0006 0.0001
752 0.0006 0.0001
761 0.0006 0.0001
1345 0.0006 0.0001
762 0.0006 0.0001
1343 0.0006 0.0001
1338 0.0006 0.0001
1337 0.0006 0.0001
1364 0.0006 0.0001
1365 0.0006 0.0001
1367 0.0006 0.0001
1368 0.0006 0.0001
1397 0.0006 0.0001
521 0.0006 0.0001
1395 0.0006 0.0001
1393 0.0006 0.0001
1392 0.0006 0.0001
1391 0.0006 0.0001
1390 0.0006 0.0001
1386 0.0006 0.0001
555 0.0006 0.0001
1384 0.0006 0.0001
1383 0.0006 0.0001
1381 0.0006 0.0002
1380 0.0006 0.0002
573 0.0006 0.0001
616 0.0006 0.0001
1374 0.0006 0.0001
1369 0.0006 0.0001
1336 0.0006 0.0001
1335 0.0006 0.0001
1332 0.0006 0.0001
887 0.0006 0.0001
895 0.0006 0.0001
1295 0.0006 0.0001
1294 0.0006 0.0001
902 0.0006 0.0001
1292 0.0006 0.0001
904 0.0006 0.0001
907 0.0006 0.0001
1289 0.0006 0.0001
908 0.0006 0.0001
1287 0.0006 0.0001
1285 0.0006 0.0001
1284 0.0006 0.0001
1282 0.0006 0.0001
919 0.0006 0.0001
1278 0.0006 0.0001
1277 0.0006 0.0001
1276 0.0006 0.0001
893 0.0006 0.0001
886 0.0006 0.0001
1331 0.0006 0.0001
1304 0.0006 0.0001
801 0.0006 0.0001
804 0.0006 0.0008
1324 0.0006 0.0001
818 0.0006 0.0001
821 0.0006 0.0001
822 0.0006 0.0001
1319 0.0006 0.0001
831 0.0006 0.0001
834 0.0006 0.0001
837 0.0006 0.0001
1314 0.0006 0.0001
1313 0.0006 0.0001
840 0.0006 0.0001
849 0.0006 0.0001
851 0.0006 0.0001
858 0.0006 0.0001
862 0.0006 0.0001
1573 0.0006 0.0001
import networkx as nx
import matplotlib.pyplot as plt
import matplotlib as mpl
# 1) Carga y componente gigante
G_air = read_dir_graph_weighted('airport.txt')
G_air_und = G_air.to_undirected()
comp = max(nx.connected_components(G_air_und), key=len)
Gg = G_air_und.subgraph(comp)
# 2) Calcula centralidades
deg_cent = nx.degree_centrality(Gg)
# 3) Normalización y colormap
values = list(deg_cent.values())
norm = mpl.colors.Normalize(vmin=min(values), vmax=max(values))
cmap = plt.cm.viridis
node_colors = [cmap(norm(deg_cent[n])) for n in Gg.nodes()]
# 4) Dibujar en un axes concreto
fig, ax = plt.subplots(figsize=(8, 6))
pos = nx.spring_layout(Gg, seed=42)
nx.draw_networkx_edges(Gg, pos, alpha=0.3, width=0.5, ax=ax)
nx.draw_networkx_nodes(Gg, pos,
node_size=50,
node_color=node_colors,
ax=ax)
# 5) Colorbar ligado a ese mismo ax
sm = mpl.cm.ScalarMappable(cmap=cmap, norm=norm)
sm.set_array([])
cbar = fig.colorbar(sm, ax=ax) # <— AQUÍ pasamos fig y ax
cbar.set_label("Degree Centrality", rotation=270, labelpad=15)
ax.set_title("Aeropuertos coloreados por Degree Centrality")
ax.axis('off')
plt.show()
import numpy as np
import networkx as nx
import matplotlib.pyplot as plt
import matplotlib as mpl
# 1) Carga y componente gigante
G_air = read_dir_graph_weighted('airport.txt')
G_air_und = G_air.to_undirected()
comp = max(nx.connected_components(G_air_und), key=len)
Gg = G_air_und.subgraph(comp).copy()
# 2) Centralidad de grado
deg_cent = nx.degree_centrality(Gg)
# 3) Layout “explosivo”
# - k más grande → nodos más separados
# - iterations suficientes para converger
pos = nx.spring_layout(Gg,
k=2, # distancia ideal entre nodos ( > default )
iterations=200,
seed=42)
# 4) Opcional: reescalar todo el layout para ampliarlo aún más
scale_factor = 3.0
pos = {n: np.array(coord) * scale_factor for n, coord in pos.items()}
# 5) Preparamos colores y tamaños
values = list(deg_cent.values())
norm = mpl.colors.Normalize(vmin=min(values), vmax=max(values))
cmap = plt.cm.viridis
node_colors= [cmap(norm(deg_cent[n])) for n in Gg.nodes()]
node_sizes = [50 + 300 * norm(deg_cent[n]) for n in Gg.nodes()]
# 6) Dibujar
fig, ax = plt.subplots(figsize=(8, 6))
nx.draw_networkx_edges(Gg, pos, alpha=0.2, width=0.5, ax=ax)
nx.draw_networkx_nodes(Gg, pos,
node_size=node_sizes,
node_color=node_colors,
ax=ax)
# 7) Colorbar
sm = mpl.cm.ScalarMappable(cmap=cmap, norm=norm)
sm.set_array([])
cbar = fig.colorbar(sm, ax=ax, fraction=0.046, pad=0.04)
cbar.set_label("Degree Centrality", rotation=270, labelpad=15)
ax.set_title("Aeropuertos (exploded) por Degree Centrality")
ax.axis('off')
plt.tight_layout()
plt.show()
import networkx as nx
import numpy as np
import random
import matplotlib.pyplot as plt
def robustness(G_orig, centrality, directed=False, trials=20):
"""
Analiza robustez de G_orig eliminando, en cada paso, todos los enlaces
de un nodo:
- Aleatorio (promedia `trials` veces sobre órdenes aleatorios).
- Dirigido (siguiendo `centrality`, de mayor a menor).
Para cada paso i (nodos desconectados = i), devuelve:
* NgN_random[i], NgN_targeted[i]
* si not directed: E_random[i], E_targeted[i]
"""
N = G_orig.number_of_nodes()
# Orden dirigido por centralidad (descendente)
target_order = sorted(centrality, key=centrality.get, reverse=True)
def one_pass(order):
G = G_orig.copy()
Ng = []
Ef = []
for node in order:
# remover todos los enlaces incidentes al nodo
if directed:
G.remove_edges_from(list(G.in_edges(node)) + list(G.out_edges(node)))
else:
G.remove_edges_from(list(G.edges(node)))
# tamaño comp gigante
if directed:
comps = [len(c) for c in nx.weakly_connected_components(G)]
else:
comps = [len(c) for c in nx.connected_components(G)]
Ng.append(max(comps) / N)
# eficiencia (solo no dirigido)
if not directed:
Ef.append(nx.global_efficiency(G))
return Ng, Ef
# 1) Targeted
Ng_t, Ef_t = one_pass(target_order)
# 2) Random (promedio)
all_Ng = []
all_Ef = []
nodes = list(G_orig.nodes())
for _ in range(trials):
order_rand = random.sample(nodes, N)
Ng_r, Ef_r = one_pass(order_rand)
all_Ng.append(Ng_r)
all_Ef.append(Ef_r)
Ng_r_mean = np.mean(all_Ng, axis=0)
Ef_r_mean = None if directed else np.mean(all_Ef, axis=0)
return {
'fraction': np.arange(1, N+1)/N,
'NgN_targeted': Ng_t,
'NgN_random': Ng_r_mean,
**({} if directed else {
'E_targeted': Ef_t,
'E_random': Ef_r_mean
})
}
def plot_robustness(curves, directed=False, title=''):
"""
Dibuja Ng/N (y eficiencia si corresponde) versus fracción de nodos removidos.
"""
x = curves['fraction']
plt.figure(figsize=(6,4))
plt.plot(x, curves['NgN_random'], '--', label='Ng/N random')
plt.plot(x, curves['NgN_targeted'], '-', label='Ng/N targeted')
if not directed:
plt.plot(x, curves['E_random'], '--', label='Eff random')
plt.plot(x, curves['E_targeted'], '-', label='Eff targeted')
plt.xlabel('Fracción de nodos desconectados')
plt.ylabel('Ng/N / Eficiencia')
plt.title(title)
plt.legend()
plt.tight_layout()
plt.show()
# === Aplicación a tus dos grafos ===
# — 1) Airport (dirigido) —
# Usamos H_air y su PageRank (pr_air) calculados en el punto c)
#curves_air = robustness(H_air, pr_air, directed=True, trials=30)
#plot_robustness(curves_air, directed=True, title='Robustez Airport (Ng/N)')
# — 2) C. elegans (no dirigido) —
# Usamos G_ce y su betweenness (btw_ce)
#curves_ce = robustness(G_ce, btw_ce, directed=False, trials=30)
#plot_robustness(curves_ce, directed=False, title='Robustez C. elegans (Ng/N & E)')
# --- Supuestos previos ---
# H_air = componente fuertemente conexa de Airport (DiGraph)
# G_ce = grafo no dirigido de C. elegans
import networkx as nx
# 1) Calculamos la centralidad de grado en ambos
deg_air = nx.degree_centrality(H_air)
deg_ce = nx.degree_centrality(G_ce)
# 2) Ejecutamos el análisis de robustez usando degree centrality
curves_air = robustness(H_air, deg_air, directed=True, trials=30)
curves_ce = robustness(G_ce, deg_ce, directed=False, trials=30)
# 3) Dibujamos las curvas
plot_robustness(curves_air, directed=True, title='Robustez Airport (Degree Centrality)')
plot_robustness(curves_ce, directed=False, title='Robustez C. elegans (Degree Centrality)')
!pip install community
Collecting community Downloading community-1.0.0b1.tar.gz (2.2 kB) Preparing metadata (setup.py): started Preparing metadata (setup.py): finished with status 'done' Requirement already satisfied: Flask in c:\users\benja\anaconda3\lib\site-packages (from community) (2.2.2) Requirement already satisfied: requests in c:\users\benja\anaconda3\lib\site-packages (from community) (2.31.0) Requirement already satisfied: Werkzeug>=2.2.2 in c:\users\benja\anaconda3\lib\site-packages (from Flask->community) (2.2.3) Requirement already satisfied: Jinja2>=3.0 in c:\users\benja\anaconda3\lib\site-packages (from Flask->community) (3.1.2) Requirement already satisfied: itsdangerous>=2.0 in c:\users\benja\anaconda3\lib\site-packages (from Flask->community) (2.0.1) Requirement already satisfied: click>=8.0 in c:\users\benja\anaconda3\lib\site-packages (from Flask->community) (8.0.4) Requirement already satisfied: charset-normalizer<4,>=2 in c:\users\benja\anaconda3\lib\site-packages (from requests->community) (2.0.4) Requirement already satisfied: idna<4,>=2.5 in c:\users\benja\anaconda3\lib\site-packages (from requests->community) (3.4) Requirement already satisfied: urllib3<3,>=1.21.1 in c:\users\benja\anaconda3\lib\site-packages (from requests->community) (1.26.16) Requirement already satisfied: certifi>=2017.4.17 in c:\users\benja\anaconda3\lib\site-packages (from requests->community) (2023.7.22) Requirement already satisfied: colorama in c:\users\benja\anaconda3\lib\site-packages (from click>=8.0->Flask->community) (0.4.6) Requirement already satisfied: MarkupSafe>=2.0 in c:\users\benja\anaconda3\lib\site-packages (from Jinja2>=3.0->Flask->community) (2.1.1) Building wheels for collected packages: community Building wheel for community (setup.py): started Building wheel for community (setup.py): finished with status 'done' Created wheel for community: filename=community-1.0.0b1-py3-none-any.whl size=2143 sha256=e0dc5cd35857ec721a60b7ccc83c2887a2eab4ddb521fce57ef5df45f25dc6de Stored in directory: c:\users\benja\appdata\local\pip\cache\wheels\b7\c9\3f\e222b011e31d3d1de1fd799caed228f770d56f66563014285d Successfully built community Installing collected packages: community Successfully installed community-1.0.0b1
Modularidad Louvain (C. elegans): 0.4953
Collecting python-louvain
Downloading python-louvain-0.16.tar.gz (204 kB)
---------------------------------------- 0.0/204.6 kB ? eta -:--:--
-------------------------------------- 204.6/204.6 kB 4.2 MB/s eta 0:00:00
Preparing metadata (setup.py): started
Preparing metadata (setup.py): finished with status 'done'
Requirement already satisfied: networkx in c:\users\benja\anaconda3\lib\site-packages (from python-louvain) (3.1)
Requirement already satisfied: numpy in c:\users\benja\anaconda3\lib\site-packages (from python-louvain) (1.24.3)
Building wheels for collected packages: python-louvain
Building wheel for python-louvain (setup.py): started
Building wheel for python-louvain (setup.py): finished with status 'done'
Created wheel for python-louvain: filename=python_louvain-0.16-py3-none-any.whl size=9403 sha256=d23074f1904cb2fdd73b06f9e201fa1d4d382d1d4f0fa5ad226d81a74f16b35c
Stored in directory: c:\users\benja\appdata\local\pip\cache\wheels\11\c1\e7\f62a211c636275e2da798bf0c307a3ae79aeddaf2524a03ce4
Successfully built python-louvain
Installing collected packages: python-louvain
Successfully installed python-louvain-0.16
Note: you may need to restart the kernel to use updated packages.
# 0) Instala dependencia para Louvain
# pip install python-louvain
import networkx as nx
import community as community_louvain # python-louvain
import matplotlib.pyplot as plt
from networkx.algorithms.community import louvain_communities
from networkx.algorithms.community.quality import modularity
def detectar_comunidades_louvain_nx(G):
coms = louvain_communities(G, weight='weight')
mod = modularity(G, coms, weight='weight')
# convertir lista de sets a dict nodo→comunidad
partition = {n:i for i, comm in enumerate(coms) for n in comm}
return partition, mod
part_ce2, mod_ce2 = detectar_comunidades_louvain_nx(G_ce)
print(f"Modularidad Louvain-NX (C. elegans): {mod_ce2:.4f}")
def detectar_comunidades_girvan_newman(G, k=None):
"""
k = número deseado de comunidades finales.
Si k=None toma la primera división (2 comunidades).
"""
comp_gen = nx.community.girvan_newman(G)
if k is None:
first_level = next(comp_gen)
return list(first_level)
else:
for communities in comp_gen:
if len(communities) >= k:
return list(communities)
return None
def dibujar_comunidades(G, partition, pos=None, title=""):
"""
partition: dict nodo→comunidad
pos: posiciones (si ya las cargaste con pickle, úsalas)
"""
if pos is None:
pos = nx.spring_layout(G, seed=42)
# agrupar nodos por comunidad
comm2nodes = {}
for n, comm in partition.items():
comm2nodes.setdefault(comm, []).append(n)
# paleta
cmap = plt.cm.tab20
plt.figure(figsize=(8,6))
for comm, nodes in comm2nodes.items():
nx.draw_networkx_nodes(
G, pos,
nodelist=nodes,
node_size=50,
node_color=[cmap(comm % 20)],
label=f"c{comm}"
)
nx.draw_networkx_edges(G, pos, alpha=0.2, width=0.5)
plt.title(title)
plt.legend(scatterpoints=1, fontsize=8)
plt.axis('off')
plt.show()
# ————————————————
# Ejemplo sobre C. elegans
G_ce = read_graph_weighted("celegans.txt").to_undirected()
# 1) Louvain
part_ce, mod_ce = detectar_comunidades_louvain_nx(G_ce)
print(f"Modularidad Louvain (C.elegans): {mod_ce:.4f}")
dibujar_comunidades(G_ce, part_ce, title="C.elegans – Louvain")
# 2) Girvan–Newman (2 comunidades)
coms_gn = detectar_comunidades_girvan_newman(G_ce, k=2)
print(f"Girvan-Newman 2 comunidades → tamaños: {[len(c) for c in coms_gn]}")
# para dibujar, convertimos la lista de sets a dict nodo→índice
part_gn = {n: i for i, comm in enumerate(coms_gn) for n in comm}
dibujar_comunidades(G_ce, part_gn, title="C.elegans – Girvan-Newman")
# ————————————————
# Ejemplo sobre Airport
#G_air = read_dir_graph_weighted("airport.txt").to_undirected()
#part_air, mod_air = detectar_comunidades_louvain_nx(G_air)
#print(f"Modularidad Louvain (Airport): {mod_air:.4f}")
# grafo no dirigido de la componente gigante
# 1) Carga y componente gigante (no dirigido)
G_air = read_dir_graph_weighted('airport.txt').to_undirected()
comp = max(nx.connected_components(G_air), key=len)
Gg = G_air.subgraph(comp).copy()
# 2) Detección de comunidades con Louvain de NX (unweighted)
# weight=None fuerza que ignore cualquier atributo 'weight'
communities = louvain_communities(Gg, weight=None)
mod_score = modularity(Gg, communities, weight=None)
print(f"Modularidad Louvain Airport (unweighted): {mod_score:.4f}")
# 3) Preparamos un dict nodo→comunidad para colorear
partition = {n:i for i, comm in enumerate(communities) for n in comm}
# 4) Dibujado
pos = nx.spring_layout(Gg, seed=42)
cmap = plt.cm.tab20
colors= [cmap(partition[n] % 20) for n in Gg.nodes()]
plt.figure(figsize=(8,6))
nx.draw_networkx_edges(Gg, pos, alpha=0.2, width=0.5)
nx.draw_networkx_nodes(Gg, pos,
node_size=50,
node_color=colors)
plt.title(f"Airport – Louvain (unweighted)\nmodularidad={mod_score:.4f}")
plt.axis('off')
plt.show()
# Girvan–Newman en Airport puede ser muy lento por tamaño; pruebes sobre muestra:
# subG = G_air.subgraph(list(G_air.nodes())[:200])
# … aplicar mismo flujo sobre subG …
Modularidad Louvain-NX (C. elegans): 0.4943 Modularidad Louvain (C.elegans): 0.4901
Girvan-Newman 2 comunidades → tamaños: [296, 1]
Modularidad Louvain (unweighted): 0.3295
# grafo no dirigido de la componente gigante
# 1) Carga y componente gigante (no dirigido)
G_air = read_dir_graph_weighted('airport.txt').to_undirected()
comp = max(nx.connected_components(G_air), key=len)
Gg = G_air.subgraph(comp).copy()
# 2) Detección de comunidades con Louvain de NX (unweighted)
# weight=None fuerza que ignore cualquier atributo 'weight'
communities = louvain_communities(Gg, weight='weight')
mod_score = modularity(Gg, communities, weight='weight')
print(f"Modularidad Louvain (weighted): {mod_score:.4f}")
# 3) Preparamos un dict nodo→comunidad para colorear
partition = {n:i for i, comm in enumerate(communities) for n in comm}
# 4) Dibujado
pos = nx.spring_layout(Gg, seed=42)
cmap = plt.cm.tab20
colors= [cmap(partition[n] % 20) for n in Gg.nodes()]
plt.figure(figsize=(8,6))
nx.draw_networkx_edges(Gg, pos, alpha=0.2, width=0.5)
nx.draw_networkx_nodes(Gg, pos,
node_size=50,
node_color=colors)
plt.title(f"Airport – Louvain (weighted)\nmodularidad={mod_score:.4f}")
plt.axis('off')
plt.show()
Modularidad Louvain (weighted): 4.3635